File indexing completed on 2025-01-19 03:53:53
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2008-07-11 0007 * Description : shared libraries list dialog common to digiKam and Showfoto 0008 * 0009 * SPDX-FileCopyrightText: 2008-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 "libsinfodlg.h" 0016 #include "digikam_config.h" 0017 0018 // Qt includes 0019 0020 #include <QStringList> 0021 #include <QString> 0022 #include <QTreeWidget> 0023 #include <QHeaderView> 0024 #include <QThread> 0025 #include <QStandardPaths> 0026 #include <QFile> 0027 #include <QTextStream> 0028 0029 #ifdef HAVE_QWEBENGINE 0030 # include <QtWebEngineWidgetsVersion> 0031 #else 0032 # include <QtWebKitWidgetsVersion> 0033 #endif 0034 0035 // KDE includes 0036 0037 #include <klocalizedstring.h> 0038 #include <kmemoryinfo.h> 0039 #include <kxmlgui_version.h> 0040 0041 // Local includes 0042 0043 #include "digikam_debug.h" 0044 #include "drawdecoder.h" 0045 #include "greycstorationfilter.h" 0046 #include "pgfutils.h" 0047 #include "digikam-lcms.h" 0048 #include "metaengine.h" 0049 #include "dngwriter.h" 0050 #include "exiftoolparser.h" 0051 #include "loadingcache.h" 0052 #include "itempropertiestab.h" 0053 0054 #ifdef HAVE_LENSFUN 0055 # include "lensfuniface.h" 0056 #endif 0057 0058 #ifdef HAVE_GEOLOCATION 0059 # include "backendmarble.h" 0060 #endif 0061 0062 #ifdef HAVE_IMAGE_MAGICK 0063 0064 // Pragma directives to reduce warnings from ImageMagick header files. 0065 # if !defined(Q_OS_DARWIN) && defined(Q_CC_GNU) 0066 # pragma GCC diagnostic push 0067 # pragma GCC diagnostic ignored "-Wignored-qualifiers" 0068 # pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" 0069 # endif 0070 0071 # if defined(Q_CC_CLANG) 0072 # pragma clang diagnostic push 0073 # pragma clang diagnostic ignored "-Wignored-qualifiers" 0074 # pragma clang diagnostic ignored "-Wkeyword-macro" 0075 # pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" 0076 # endif 0077 0078 # include <Magick++.h> 0079 0080 // Restore warnings 0081 0082 # if defined(Q_CC_CLANG) 0083 # pragma clang diagnostic pop 0084 # endif 0085 0086 # if !defined(Q_OS_DARWIN) && defined(Q_CC_GNU) 0087 # pragma GCC diagnostic pop 0088 # endif 0089 0090 #endif 0091 0092 // C ANSI includes 0093 0094 #ifndef Q_OS_WIN 0095 extern "C" 0096 { 0097 #endif 0098 0099 #ifdef HAVE_JASPER 0100 0101 # if defined(Q_CC_CLANG) 0102 # pragma clang diagnostic push 0103 # pragma clang diagnostic ignored "-Werror" 0104 # pragma clang diagnostic ignored "-Wundef" 0105 # endif 0106 0107 # include <jasper/jas_version.h> 0108 0109 # if defined(Q_CC_CLANG) 0110 # pragma clang diagnostic pop 0111 # endif 0112 0113 #endif 0114 0115 #include <png.h> 0116 #include <tiffvers.h> 0117 0118 #ifdef HAVE_HEIF 0119 # include <libheif/heif_version.h> 0120 #endif 0121 0122 // libx265 includes 0123 0124 #if defined(__clang__) 0125 # pragma clang diagnostic push 0126 # pragma clang diagnostic ignored "-Wundef" 0127 # pragma clang diagnostic ignored "-Wgnu-anonymous-struct" 0128 # pragma clang diagnostic ignored "-Wnested-anon-types" 0129 # pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" 0130 #endif 0131 0132 #ifdef HAVE_X265 0133 # include <x265.h> 0134 #endif 0135 0136 #if defined(__clang__) 0137 # pragma clang diagnostic pop 0138 #endif 0139 0140 // Avoid Warnings under Win32 0141 #undef HAVE_STDLIB_H 0142 #undef HAVE_STDDEF_H 0143 #include <jpeglib.h> 0144 0145 #ifndef Q_OS_WIN 0146 } 0147 #endif 0148 0149 #include "digikam_opencv.h" 0150 0151 // defined in OpenCV core/private.hpp 0152 namespace cv 0153 { 0154 const char* currentParallelFramework(); 0155 } 0156 0157 namespace Digikam 0158 { 0159 0160 LibsInfoDlg::LibsInfoDlg(QWidget* const parent) 0161 : InfoDlg(parent) 0162 { 0163 setWindowTitle(i18nc("@title:window", "Shared Libraries and Components Information")); 0164 0165 static const char* CONTEXT = "@item: Component information, see help->components"; 0166 static const QString SUPPORTED_YES = i18nc("@item: component is supported/available", "Yes"); 0167 static const QString SUPPORTED_NO = i18nc("@item: component is not available/supported", "No"); 0168 0169 listView()->setHeaderLabels(QStringList() << QLatin1String("Properties") << QLatin1String("Value")); // Hidden header -> no i18n 0170 listView()->setSortingEnabled(true); 0171 listView()->setRootIsDecorated(true); 0172 listView()->setSelectionMode(QAbstractItemView::SingleSelection); 0173 listView()->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 0174 listView()->setAllColumnsShowFocus(true); 0175 listView()->setColumnCount(2); 0176 listView()->header()->setSectionResizeMode(QHeaderView::Stretch); 0177 listView()->header()->hide(); 0178 0179 // NOTE: by default set a list of common components information used by Showfoto and digiKam. 0180 0181 m_features = new QTreeWidgetItem(listView(), QStringList() << i18nc("@title", "Features")); 0182 listView()->addTopLevelItem(m_features); 0183 0184 new QTreeWidgetItem(m_features, QStringList() << 0185 i18nc(CONTEXT, "Parallelized demosaicing") << checkTriState(DRawDecoder::librawUseGomp())); 0186 0187 #ifdef HAVE_QTXMLPATTERNS 0188 new QTreeWidgetItem(m_features, QStringList() << 0189 i18nc(CONTEXT, "Rajce support") << SUPPORTED_YES); 0190 #else 0191 new QTreeWidgetItem(m_features, QStringList() << 0192 i18nc(CONTEXT, "Rajce support") << SUPPORTED_NO); 0193 #endif 0194 0195 new QTreeWidgetItem(m_features, QStringList() << 0196 i18nc(CONTEXT, "Exiv2 supports XMP metadata") << (MetaEngine::supportXmp() ? SUPPORTED_YES : SUPPORTED_NO)); 0197 0198 new QTreeWidgetItem(m_features, QStringList() << 0199 i18nc(CONTEXT, "Exiv2 supports Base Media") << (MetaEngine::supportBmff() ? SUPPORTED_YES : SUPPORTED_NO)); 0200 0201 new QTreeWidgetItem(m_features, QStringList() << 0202 i18nc(CONTEXT, "Exiv2 supports JPEG-XL metadata") << (MetaEngine::supportJpegXL() ? SUPPORTED_YES : SUPPORTED_NO)); 0203 0204 // --- 0205 0206 m_libraries = new QTreeWidgetItem(listView(), QStringList() << i18nc("@title", "Libraries")); 0207 listView()->addTopLevelItem(m_libraries); 0208 0209 0210 new QTreeWidgetItem(m_libraries, QStringList() << 0211 i18nc(CONTEXT, "Qt Framework") << QLatin1String(qVersion())); 0212 0213 new QTreeWidgetItem(m_libraries, QStringList() << 0214 i18nc(CONTEXT, "KDE Framework") << QLatin1String(KXMLGUI_VERSION_STRING)); 0215 0216 new QTreeWidgetItem(m_libraries, QStringList() << 0217 i18nc(CONTEXT, "LibRaw") << DRawDecoder::librawVersion()); 0218 0219 #ifdef HAVE_EIGEN3 0220 new QTreeWidgetItem(m_libraries, QStringList() << 0221 i18nc(CONTEXT, "Eigen") << QLatin1String(EIGEN3_VERSION_STRING)); 0222 #else 0223 new QTreeWidgetItem(m_features, QStringList() << 0224 i18nc(CONTEXT, "Eigen support") << SUPPORTED_NO); 0225 #endif 0226 0227 #ifdef HAVE_QWEBENGINE 0228 new QTreeWidgetItem(m_libraries, QStringList() << 0229 i18nc(CONTEXT, "Qt WebEngine version") << QLatin1String(QTWEBENGINEWIDGETS_VERSION_STR)); 0230 #else 0231 new QTreeWidgetItem(m_libraries, QStringList() << 0232 i18nc(CONTEXT, "Qt WebKit version") << QLatin1String(QTWEBKITWIDGETS_VERSION_STR)); 0233 #endif 0234 0235 #ifdef HAVE_QMULTIMEDIA 0236 new QTreeWidgetItem(m_features, QStringList() << 0237 i18nc(CONTEXT, "Qt Multimedia support") << SUPPORTED_YES); 0238 #else 0239 new QTreeWidgetItem(m_features, QStringList() << 0240 i18nc(CONTEXT, "Qt Multimedia support") << SUPPORTED_YES); 0241 #endif 0242 0243 new QTreeWidgetItem(m_libraries, QStringList() << 0244 i18nc(CONTEXT, "Exiv2") << MetaEngine::Exiv2Version()); 0245 0246 ExifToolParser* const parser = new ExifToolParser(this); 0247 ExifToolParser::ExifToolData parsed; 0248 0249 if (parser->version()) 0250 { 0251 parsed = parser->currentData(); 0252 QString etVersion = parsed.find(QLatin1String("VERSION_STRING")).value()[0].toString(); 0253 new QTreeWidgetItem(m_libraries, QStringList() << 0254 i18nc(CONTEXT, "ExifTool") << etVersion); 0255 } 0256 else 0257 { 0258 new QTreeWidgetItem(m_features, QStringList() << 0259 i18nc(CONTEXT, "ExifTool support") << SUPPORTED_NO); 0260 } 0261 0262 #ifdef HAVE_LENSFUN 0263 new QTreeWidgetItem(m_libraries, QStringList() << 0264 i18nc(CONTEXT, "LensFun") << LensFunIface::lensFunVersion()); 0265 #else 0266 new QTreeWidgetItem(m_features, QStringList() << 0267 i18nc(CONTEXT, "LensFun support") << SUPPORTED_NO); 0268 #endif 0269 0270 #ifdef HAVE_IMAGE_MAGICK 0271 new QTreeWidgetItem(m_libraries, QStringList() << 0272 i18nc(CONTEXT, "ImageMagick codecs") << QLatin1String(MagickLibVersionText)); 0273 #else 0274 new QTreeWidgetItem(m_features, QStringList() << 0275 i18nc(CONTEXT, "ImageMagick codecs support") << SUPPORTED_NO); 0276 #endif 0277 0278 #ifdef HAVE_HEIF 0279 new QTreeWidgetItem(m_libraries, QStringList() << 0280 i18nc(CONTEXT, "LibHEIF") << QLatin1String(LIBHEIF_VERSION)); 0281 new QTreeWidgetItem(m_features, QStringList() << 0282 i18nc(CONTEXT, "HEIF reading support") << SUPPORTED_YES); 0283 #else 0284 new QTreeWidgetItem(m_features, QStringList() << 0285 i18nc(CONTEXT, "HEIF reading support") << SUPPORTED_NO); 0286 #endif 0287 0288 #ifdef HAVE_X265 0289 const x265_api* const x265api = x265_api_get(0); 0290 0291 new QTreeWidgetItem(m_libraries, QStringList() << 0292 i18nc(CONTEXT, "Libx265") << (x265api ? QLatin1String(x265api->version_str) 0293 : i18nc("@info: version", "Unknown"))); 0294 new QTreeWidgetItem(m_features, QStringList() << 0295 i18nc(CONTEXT, "HEIF writing support") << SUPPORTED_YES); 0296 #else 0297 new QTreeWidgetItem(m_features, QStringList() << 0298 i18nc(CONTEXT, "HEIF Writing support") << SUPPORTED_NO); 0299 #endif 0300 0301 QString tiffver = QLatin1String(TIFFLIB_VERSION_STR); 0302 tiffver = tiffver.left(tiffver.indexOf(QLatin1Char('\n'))); 0303 tiffver = tiffver.section(QLatin1Char(' '), 2, 2); 0304 new QTreeWidgetItem(m_libraries, QStringList() << 0305 i18nc(CONTEXT, "LibTIFF") << tiffver); 0306 0307 new QTreeWidgetItem(m_libraries, QStringList() << 0308 i18nc(CONTEXT, "LibPNG") << QLatin1String(PNG_LIBPNG_VER_STRING)); 0309 0310 new QTreeWidgetItem(m_libraries, QStringList() << 0311 i18nc(CONTEXT, "LibJPEG") << QString::number(JPEG_LIB_VERSION)); 0312 0313 new QTreeWidgetItem(m_libraries, QStringList() << 0314 i18nc(CONTEXT, "LibCImg") << GreycstorationFilter::cimgVersionString()); 0315 0316 new QTreeWidgetItem(m_libraries, QStringList() << 0317 i18nc(CONTEXT, "LibLCMS") << QString::number(LCMS_VERSION)); 0318 0319 new QTreeWidgetItem(m_libraries, QStringList() << 0320 i18nc(CONTEXT, "LibPGF") << PGFUtils::libPGFVersion()); 0321 0322 new QTreeWidgetItem(m_libraries, QStringList() << 0323 i18nc(CONTEXT, "XMP SDK") << DNGWriter::xmpSdkVersion()); 0324 0325 new QTreeWidgetItem(m_libraries, QStringList() << 0326 i18nc(CONTEXT, "DNG SDK") << DNGWriter::dngSdkVersion()); 0327 0328 #ifdef HAVE_JASPER 0329 new QTreeWidgetItem(m_libraries, QStringList() << 0330 i18nc(CONTEXT, "LibJasper") << QLatin1String(jas_getversion())); 0331 #else 0332 new QTreeWidgetItem(m_features, QStringList() << 0333 i18nc(CONTEXT, "LibJasper support") << SUPPORTED_NO); 0334 #endif 0335 0336 #ifdef HAVE_GEOLOCATION 0337 new QTreeWidgetItem(m_libraries, QStringList() << 0338 i18nc(CONTEXT, "Geolocation support") << SUPPORTED_YES); 0339 #else 0340 new QTreeWidgetItem(m_features, QStringList() << 0341 i18nc(CONTEXT, "Geolocation support") << SUPPORTED_NO); 0342 #endif 0343 0344 #ifdef HAVE_SONNET 0345 0346 new QTreeWidgetItem(m_features, QStringList() << 0347 i18nc(CONTEXT, "Spell-Checking support") << SUPPORTED_YES); 0348 0349 #else 0350 0351 new QTreeWidgetItem(m_features, QStringList() << 0352 i18nc(CONTEXT, "Spell-Checking support") << SUPPORTED_NO); 0353 0354 #endif 0355 0356 int nbcore = QThread::idealThreadCount(); 0357 new QTreeWidgetItem(m_features, QStringList() << 0358 i18ncp(CONTEXT, "CPU core", "CPU cores", nbcore) << QString::fromLatin1("%1").arg(nbcore)); 0359 0360 KMemoryInfo memInfo; 0361 0362 if (!memInfo.isNull()) 0363 { 0364 quint64 available = memInfo.totalPhysical(); 0365 0366 if (available > 0) 0367 { 0368 new QTreeWidgetItem(m_features, QStringList() << 0369 i18nc(CONTEXT, "Memory available") << ItemPropertiesTab::humanReadableBytesCount(available)); 0370 } 0371 else 0372 { 0373 new QTreeWidgetItem(m_features, QStringList() << 0374 i18nc(CONTEXT, "Memory available") << i18nc("@item: information about memory", "Unknown")); 0375 } 0376 } 0377 0378 quint64 cacheSize = LoadingCache::cache()->getCacheSize(); 0379 0380 new QTreeWidgetItem(m_features, QStringList() << 0381 i18nc(CONTEXT, "Image cache size") << ItemPropertiesTab::humanReadableBytesCount(cacheSize)); 0382 0383 // NOTE: MANIFEST.txt is a text file generated with the bundles and listing all git revisions of rolling release components. 0384 // One section title start with '+'. 0385 // All component revisions are listed below line by line with the name and the revision separated by ':'. 0386 // More than one section can be listed in manifest. 0387 0388 const QString gitRevs = QStandardPaths::locate(QStandardPaths::AppDataLocation, 0389 QLatin1String("MANIFEST.txt")); 0390 0391 if (!gitRevs.isEmpty() && QFile::exists(gitRevs)) 0392 { 0393 QFile file(gitRevs); 0394 0395 if (!file.open(QIODevice::ReadOnly)) 0396 { 0397 return; 0398 } 0399 0400 qCDebug(DIGIKAM_WIDGETS_LOG) << "Git revisions manifest file found:" << gitRevs; 0401 0402 QTreeWidgetItem* const manifestHead = new QTreeWidgetItem(listView(), QStringList() << i18nc("@item: component info", "Manifests")); 0403 listView()->addTopLevelItem(manifestHead); 0404 0405 QTextStream in(&file); 0406 QTreeWidgetItem* manifestEntry = nullptr; 0407 0408 while (!in.atEnd()) 0409 { 0410 QString line = in.readLine(); 0411 0412 if (line.isEmpty()) 0413 { 0414 continue; 0415 } 0416 0417 if (line.startsWith(QLatin1Char('+'))) 0418 { 0419 manifestEntry = new QTreeWidgetItem(manifestHead, QStringList() << line.remove(QLatin1Char('+'))); 0420 } 0421 else if (manifestEntry) 0422 { 0423 new QTreeWidgetItem(manifestEntry, line.split(QLatin1Char(':'))); 0424 } 0425 } 0426 0427 file.close(); 0428 } 0429 0430 QTreeWidgetItem* const opencvHead = new QTreeWidgetItem(listView(), QStringList() << i18nc("@item: opencv info", "OpenCV Configuration")); 0431 listView()->addTopLevelItem(opencvHead); 0432 0433 // --- OpenCV::OpenCL features 0434 0435 try 0436 { 0437 if (!cv::ocl::haveOpenCL() || !cv::ocl::useOpenCL()) 0438 { 0439 new QTreeWidgetItem(opencvHead, QStringList() << 0440 i18nc(CONTEXT, "OpenCL availability") << SUPPORTED_NO); 0441 } 0442 else 0443 { 0444 std::vector<cv::ocl::PlatformInfo> platforms; 0445 cv::ocl::getPlatfomsInfo(platforms); 0446 0447 if (platforms.empty()) 0448 { 0449 new QTreeWidgetItem(opencvHead, QStringList() << 0450 i18nc(CONTEXT, "OpenCL availability") << SUPPORTED_NO); 0451 0452 } 0453 else 0454 { 0455 QTreeWidgetItem* const oclplfrm = new QTreeWidgetItem(opencvHead, QStringList() << i18nc(CONTEXT, "OpenCL platform")); 0456 0457 for (size_t i = 0 ; i < platforms.size() ; i++) 0458 { 0459 const cv::ocl::PlatformInfo* platform = &platforms[i]; 0460 QTreeWidgetItem* const plfrm = new QTreeWidgetItem(oclplfrm, QStringList() << QString::fromStdString(platform->name())); 0461 0462 cv::ocl::Device current_device; 0463 0464 for (int j = 0 ; j < platform->deviceNumber() ; j++) 0465 { 0466 platform->getDevice(current_device, j); 0467 QString deviceTypeStr = openCVGetDeviceTypeString(current_device); 0468 0469 new QTreeWidgetItem(plfrm, QStringList() 0470 << deviceTypeStr << QString::fromStdString(current_device.name()) + 0471 QLatin1String(" (") + QString::fromStdString(current_device.version()) + QLatin1Char(')')); 0472 } 0473 } 0474 0475 const cv::ocl::Device& device = cv::ocl::Device::getDefault(); 0476 0477 if (!device.available()) 0478 { 0479 new QTreeWidgetItem(opencvHead, QStringList() << 0480 i18nc(CONTEXT, "OpenCL device") << SUPPORTED_NO); 0481 } 0482 else 0483 { 0484 QTreeWidgetItem* const ocldev = new QTreeWidgetItem(opencvHead, QStringList() << i18nc(CONTEXT, "OpenCL Device")); 0485 QString deviceTypeStr = openCVGetDeviceTypeString(device); 0486 0487 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Type") << deviceTypeStr); 0488 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Name") << QString::fromStdString(device.name())); 0489 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Version") << QString::fromStdString(device.version())); 0490 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Driver version") << QString::fromStdString(device.driverVersion())); 0491 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Address bits") << QString::number(device.addressBits())); 0492 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Compute units") << QString::number(device.maxComputeUnits())); 0493 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Max work group size") << QString::number(device.maxWorkGroupSize())); 0494 0495 QString localMemorySizeStr = openCVBytesToStringRepr(device.localMemSize()); 0496 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Local memory size") << localMemorySizeStr); 0497 0498 QString maxMemAllocSizeStr = openCVBytesToStringRepr(device.maxMemAllocSize()); 0499 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Max memory allocation size") << maxMemAllocSizeStr); 0500 0501 QString doubleSupportStr = (device.doubleFPConfig() > 0) ? SUPPORTED_YES : SUPPORTED_NO; 0502 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Double support") << doubleSupportStr); 0503 0504 QString halfSupportStr = (device.halfFPConfig() > 0) ? SUPPORTED_YES : SUPPORTED_NO; 0505 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Half support") << halfSupportStr); 0506 0507 QString isUnifiedMemoryStr = device.hostUnifiedMemory() ? SUPPORTED_YES : SUPPORTED_NO; 0508 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Host unified memory") << isUnifiedMemoryStr); 0509 0510 QString haveAmdBlasStr = cv::ocl::haveAmdBlas() ? SUPPORTED_YES : SUPPORTED_NO; 0511 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Has AMD Blas") << haveAmdBlasStr); 0512 0513 QString haveAmdFftStr = cv::ocl::haveAmdFft() ? SUPPORTED_YES : SUPPORTED_NO; 0514 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Has AMD Fft") << haveAmdFftStr); 0515 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Preferred vector width char") << QString::number(device.preferredVectorWidthChar())); 0516 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Preferred vector width short") << QString::number(device.preferredVectorWidthShort())); 0517 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Preferred vector width int") << QString::number(device.preferredVectorWidthInt())); 0518 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Preferred vector width long") << QString::number(device.preferredVectorWidthLong())); 0519 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Preferred vector width float") << QString::number(device.preferredVectorWidthFloat())); 0520 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Preferred vector width double") << QString::number(device.preferredVectorWidthDouble())); 0521 new QTreeWidgetItem(ocldev, QStringList() << i18nc(CONTEXT, "Preferred vector width half") << QString::number(device.preferredVectorWidthHalf())); 0522 0523 QTreeWidgetItem* const ocldevext = new QTreeWidgetItem(opencvHead, QStringList() << i18nc(CONTEXT, "OpenCL Device extensions")); 0524 QString extensionsStr = QString::fromStdString(device.extensions()); 0525 int pos = 0; 0526 0527 while (pos < extensionsStr.size()) 0528 { 0529 int pos2 = extensionsStr.indexOf(QLatin1Char(' '), pos); 0530 0531 if (pos2 == -1) 0532 { 0533 pos2 = extensionsStr.size(); 0534 } 0535 0536 if (pos2 > pos) 0537 { 0538 QString extensionName = extensionsStr.mid(pos, pos2 - pos); 0539 new QTreeWidgetItem(ocldevext, QStringList() << extensionName << SUPPORTED_YES); 0540 } 0541 0542 pos = pos2 + 1; 0543 } 0544 } 0545 } 0546 } 0547 } 0548 catch (...) 0549 { 0550 new QTreeWidgetItem(opencvHead, QStringList() << i18nc(CONTEXT, "OpenCL availability") << SUPPORTED_NO); 0551 } 0552 0553 // --- OpenCV::Hardware features 0554 0555 try 0556 { 0557 QTreeWidgetItem* const ocvhdw = new QTreeWidgetItem(opencvHead, QStringList() << i18nc(CONTEXT, "Hardware features")); 0558 int count = 0; 0559 0560 for (int i = 0 ; i < CV_HARDWARE_MAX_FEATURE ; i++) 0561 { 0562 QString name = QString::fromStdString(cv::getHardwareFeatureName(i)); 0563 0564 if (name.isEmpty()) 0565 { 0566 continue; 0567 } 0568 0569 bool enabled = cv::checkHardwareSupport(i); 0570 0571 if (enabled) 0572 { 0573 count++; 0574 new QTreeWidgetItem(ocvhdw, QStringList() << name << (enabled ? SUPPORTED_YES : SUPPORTED_NO)); 0575 } 0576 } 0577 } 0578 catch (...) 0579 { 0580 new QTreeWidgetItem(opencvHead, QStringList() << i18nc(CONTEXT, "Hardware features availability") << SUPPORTED_NO); 0581 } 0582 0583 // --- OpenCV::Threads features 0584 0585 try 0586 { 0587 QTreeWidgetItem* const ocvthreads = new QTreeWidgetItem(opencvHead, QStringList() << i18nc(CONTEXT, "Threads features")); 0588 0589 QString parallelFramework = QString::fromStdString(cv::currentParallelFramework()); 0590 0591 if (!parallelFramework.isEmpty()) 0592 { 0593 new QTreeWidgetItem(ocvthreads, QStringList() << i18nc(CONTEXT, "Number of Threads") << QString::number(cv::getNumThreads())); 0594 new QTreeWidgetItem(ocvthreads, QStringList() << i18nc(CONTEXT, "Parallel framework") << parallelFramework); 0595 } 0596 } 0597 catch (...) 0598 { 0599 new QTreeWidgetItem(opencvHead, QStringList() << i18nc(CONTEXT, "Threads features availability") << SUPPORTED_NO); 0600 } 0601 } 0602 0603 LibsInfoDlg::~LibsInfoDlg() 0604 { 0605 } 0606 0607 QString LibsInfoDlg::checkTriState(int value) const 0608 { 0609 switch (value) 0610 { 0611 case true: 0612 { 0613 return i18nc("@info: tri state", "Yes"); 0614 } 0615 0616 case false: 0617 { 0618 return i18nc("@info: tri state", "No"); 0619 } 0620 0621 default: 0622 { 0623 return i18nc("@info: tri state", "Unknown"); 0624 } 0625 } 0626 } 0627 0628 QString LibsInfoDlg::openCVBytesToStringRepr(size_t value) const 0629 { 0630 size_t b = value % 1024; 0631 value /= 1024; 0632 0633 size_t kb = value % 1024; 0634 value /= 1024; 0635 0636 size_t mb = value % 1024; 0637 value /= 1024; 0638 0639 size_t gb = value; 0640 0641 QString s; 0642 QTextStream stream(&s); 0643 0644 if (gb > 0) 0645 { 0646 stream << gb << " GB "; 0647 } 0648 0649 if (mb > 0) 0650 { 0651 stream << mb << " MB "; 0652 } 0653 0654 if (kb > 0) 0655 { 0656 stream << kb << " KB "; 0657 } 0658 0659 if (b > 0) 0660 { 0661 stream << b << " B"; 0662 } 0663 0664 if (s[s.size() - 1] == QLatin1Char(' ')) 0665 { 0666 s = s.mid(0, s.size() - 1); 0667 } 0668 0669 return s; 0670 } 0671 0672 QString LibsInfoDlg::openCVGetDeviceTypeString(const cv::ocl::Device& device) 0673 { 0674 if (device.type() == cv::ocl::Device::TYPE_CPU) 0675 { 0676 return QLatin1String("CPU"); 0677 } 0678 0679 if (device.type() == cv::ocl::Device::TYPE_GPU) 0680 { 0681 if (device.hostUnifiedMemory()) 0682 { 0683 return QLatin1String("iGPU"); 0684 } 0685 else 0686 { 0687 return QLatin1String("dGPU"); 0688 } 0689 } 0690 0691 return QLatin1String("unknown"); 0692 } 0693 0694 } // namespace Digikam 0695 0696 #include "moc_libsinfodlg.cpp"