Coverage Report

Created: 2026-01-25 07:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/kio-extras/thumbnail/imagecreator.cpp
Line
Count
Source
1
/*  This file is part of the KDE libraries
2
    SPDX-FileCopyrightText: 2000 Carsten Pfeiffer <pfeiffer@kde.org>
3
    SPDX-FileCopyrightText: 2000 Malte Starostik <malte@kde.org>
4
5
    SPDX-License-Identifier: LGPL-2.0-or-later
6
*/
7
8
#include "imagecreator.h"
9
10
#include <QImageReader>
11
12
#include <KMemoryInfo>
13
#include <KPluginFactory>
14
15
0
K_PLUGIN_CLASS_WITH_JSON(ImageCreator, "imagethumbnail.json")
Unexecuted instantiation: imagethumbnail_factory::tr(char const*, char const*, int)
Unexecuted instantiation: imagethumbnail_factory::~imagethumbnail_factory()
16
0
17
0
ImageCreator::ImageCreator(QObject *parent, const QVariantList &args)
18
17.7k
    : KIO::ThumbnailCreator(parent, args)
19
17.7k
{
20
17.7k
}
21
22
35.5k
#define MiB(bytes) ((bytes)*1024ll * 1024ll)
23
17.7k
#define GiB(bytes) (MiB(bytes) * 1024ll)
24
25
// When the ram check is disabled or not available, this is the expected default value of free RAM
26
17.7k
#define DEFAULT_FREE_RAM GiB(2)
27
28
// The maximum usable RAM is the free RAM is divided by this number:
29
// if the calculated image size is greater than this value, the preview is skipped.
30
17.7k
#define RAM_DIVISOR 3
31
32
// An image smaller than 64 MiB will be loaded even if the usable RAM check fails.
33
17.7k
#define MINIMUM_GUARANTEED_SIZE MiB(64)
34
35
/**
36
 * @brief maximumThumbnailRam
37
 * Calculates the maximum RAM that can be used to generate the thumbnail.
38
 *
39
 * The value returned is a third of the available free RAM.
40
 */
41
qint64 maximumThumbnailRam()
42
17.7k
{
43
    // read available RAM (physical free ram only)
44
17.7k
    auto freeRam = DEFAULT_FREE_RAM;
45
46
17.7k
    KMemoryInfo m;
47
17.7k
    if (!m.isNull()) {
48
17.7k
        freeRam = qint64(m.availablePhysical());
49
17.7k
    }
50
51
    /*
52
     * NOTE 1: a minimal 64MiB image is always guaranteed (this small size should never cause OS thrashing).
53
     * NOTE 2: the freeRam is divided by 3 for the following reasons:
54
     *         - the image could be converted (e.g. when depth() != 32)
55
     *         - we don't want to use all free ram for a thumbnail :)
56
     */
57
17.7k
    return std::max(MINIMUM_GUARANTEED_SIZE, freeRam / RAM_DIVISOR);
58
17.7k
}
59
60
KIO::ThumbnailResult ImageCreator::create(const KIO::ThumbnailRequest &request)
61
17.7k
{
62
    // create image preview
63
17.7k
    QImageReader ir(request.url().toLocalFile());
64
65
    /* The idea is to read the free ram and try to avoid OS trashing when the
66
     * image is too big:
67
     * - Qt 6: we can simply limit the maximum size that image reader can handle.
68
     * - Qt 5: the image plugin that allows big images should help us by implementing
69
     *         the QImageIOHandler::Size option (TIFF, PSB and XCF already have).
70
     */
71
17.7k
    auto ram = maximumThumbnailRam();
72
17.7k
    QImageReader::setAllocationLimit(ram / 1024 / 1024);
73
74
17.7k
    ir.setAutoTransform(true);
75
17.7k
    ir.setDecideFormatFromContent(true);
76
17.7k
    if (ir.format() == QByteArray("raw")) {
77
        // make preview generation of raw files ~3 times faster (requires setDecideFormatFromContent(true))
78
0
        ir.setQuality(1);
79
0
    }
80
81
17.7k
    QImage img;
82
17.7k
    ir.read(&img);
83
84
17.7k
    if (!img.isNull()) {
85
6.65k
        return KIO::ThumbnailResult::pass(img);
86
6.65k
    }
87
88
11.1k
    return KIO::ThumbnailResult::fail();
89
17.7k
}
90
91
#include "imagecreator.moc"
92
#include "moc_imagecreator.cpp"