/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" |