LCOV - code coverage report
Current view: top level - src/utilities - ImageGrabber.cpp (source / functions) Coverage Total Hit
Test: coverage.info.cleaned Lines: 100.0 % 48 48
Test Date: 2026-04-19 00:35:54 Functions: 100.0 % 5 5

            Line data    Source code
       1              : #include "ImageGrabber.h"
       2              : #include "QBatchWebDownload.h"
       3              : 
       4              : #include <QMimeDatabase>
       5              : #include <QSvgRenderer>
       6              : #include <QtConcurrent>
       7              : 
       8           59 : ImageGrabber::ImageGrabber(QObject *parent, QNetworkAccessManager* networkManager) :
       9              :     QObject(parent),
      10           59 :     batchDownloader(new QBatchWebDownload(30000, 10, this, networkManager))
      11              : {
      12           59 :     connect(batchDownloader, &QBatchWebDownload::finished,
      13           59 :             this, &ImageGrabber::onBatchFinished);
      14           59 :     connect(&processWatcher, &QFutureWatcher<void>::finished,
      15           59 :             this, &ImageGrabber::finished);
      16           59 : }
      17              : 
      18           19 : void ImageGrabber::fetchUrl(const QUrl &url)
      19              : {
      20           19 :     QList<QUrl> urls;
      21           19 :     urls.append(url);
      22           19 :     fetchUrls(urls);
      23           19 : }
      24              : 
      25           35 : void ImageGrabber::fetchUrls(const QList<QUrl> &urls)
      26              : {
      27           35 :     results.clear();
      28           35 :     batchDownloader->get(urls);
      29           35 : }
      30              : 
      31           35 : void ImageGrabber::onBatchFinished()
      32              : {
      33              :     // Capture batch results on the main thread, then process on a background
      34              :     // thread to avoid blocking the UI during image decoding and MIME detection.
      35           35 :     QMap<QUrl, BatchWebDownloadResult> batchResults = batchDownloader->results();
      36              : 
      37              :     // Fast path: no images to process.
      38           35 :     if (batchResults.isEmpty()) {
      39            1 :         emit finished();
      40            1 :         return;
      41              :     }
      42              : 
      43           68 :     auto future = QtConcurrent::run([this, batchResults]() {
      44           34 :         QMimeDatabase mimeDb;
      45              : 
      46           82 :         for (auto it = batchResults.constBegin(); it != batchResults.constEnd(); ++it) {
      47           48 :             const QUrl& url = it.key();
      48           48 :             const BatchWebDownloadResult& batchResult = it.value();
      49              : 
      50           48 :             ImageData imageData;
      51              : 
      52           48 :             if (batchResult.success && !batchResult.data.isEmpty()) {
      53           40 :                 QMimeType mimeType = mimeDb.mimeTypeForData(batchResult.data);
      54           40 :                 imageData.mimeType = mimeType.name();
      55              : 
      56           40 :                 if (mimeType.name() == "image/svg+xml") {
      57              :                     // Use QSvgRenderer to get the SVG's logical dimensions.
      58              :                     // QImage::fromData() rasterizes SVGs at an arbitrary size
      59              :                     // that doesn't reflect their actual width/height.
      60            3 :                     QSvgRenderer renderer(batchResult.data);
      61            3 :                     if (renderer.isValid()) {
      62            3 :                         QSize size = renderer.defaultSize();
      63            3 :                         imageData.image = QImage(size, QImage::Format_ARGB32);
      64            3 :                         imageData.rawData = batchResult.data;
      65              :                     }
      66            3 :                 } else {
      67           37 :                     QImage image = QImage::fromData(batchResult.data);
      68           37 :                     if (!image.isNull()) {
      69           36 :                         imageData.image = image;
      70           36 :                         imageData.rawData = batchResult.data;
      71              :                     }
      72           37 :                 }
      73           40 :             }
      74              : 
      75           48 :             results.insert(url, imageData);
      76           48 :         }
      77           68 :     });
      78           34 :     processWatcher.setFuture(future);
      79           35 : }
        

Generated by: LCOV version 2.0-1