1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <qsharedimageprovider_p.h>
5#include <private/qquickpixmapcache_p.h>
6#include <private/qimage_p.h>
7#include <QImageReader>
8#include <QFileInfo>
9#include <QDir>
10
11Q_DECLARE_METATYPE(QQuickImageProviderOptions)
12
13QT_BEGIN_NAMESPACE
14
15QuickSharedImageLoader::QuickSharedImageLoader(QObject *parent) : QSharedImageLoader(parent) {}
16
17QImage QuickSharedImageLoader::loadFile(const QString &path, ImageParameters *params)
18{
19 QImageReader imgio(path);
20 QSize realSize = imgio.size();
21 QSize requestSize;
22 QQuickImageProviderOptions options;
23 if (params) {
24 requestSize = params->value(i: RequestedSize).toSize();
25 options = params->value(i: ProviderOptions).value<QQuickImageProviderOptions>();
26 }
27
28 QSize scSize = QQuickImageProviderWithOptions::loadSize(originalSize: imgio.size(), requestedSize: requestSize, format: imgio.format(), options);
29
30 if (scSize.isValid())
31 imgio.setScaledSize(scSize);
32
33 QImage image;
34 if (imgio.read(image: &image)) {
35 if (realSize.isEmpty())
36 realSize = image.size();
37 // Make sure we have acceptable format for texture uploader, or it will convert & lose sharing
38 // This mimics the testing & conversion normally done by the quick pixmapcache & texturefactory
39 if (image.format() != QImage::Format_RGB32 && image.format() != QImage::Format_ARGB32_Premultiplied) {
40 QImage::Format newFmt = QImage::Format_RGB32;
41 if (image.hasAlphaChannel() && image.data_ptr()->checkForAlphaPixels())
42 newFmt = QImage::Format_ARGB32_Premultiplied;
43 qCDebug(lcSharedImage) << "Convert on load from format" << image.format() << "to" << newFmt;
44 image = image.convertToFormat(f: newFmt);
45 }
46 }
47
48 if (params && params->size() > OriginalSize)
49 params->replace(i: OriginalSize, t: realSize);
50
51 return image;
52}
53
54QString QuickSharedImageLoader::key(const QString &path, ImageParameters *params)
55{
56 QSize reqSz;
57 QQuickImageProviderOptions opts;
58 if (params) {
59 reqSz = params->value(i: RequestedSize).toSize();
60 opts = params->value(i: ProviderOptions).value<QQuickImageProviderOptions>();
61 }
62 if (!reqSz.isValid())
63 return path;
64 int aspect = opts.preserveAspectRatioCrop() || opts.preserveAspectRatioFit() ? 1 : 0;
65
66 QString key = path + QStringLiteral("_%1x%2_%3").arg(a: reqSz.width()).arg(a: reqSz.height()).arg(a: aspect);
67 qCDebug(lcSharedImage) << "KEY:" << key;
68 return key;
69}
70
71SharedImageProvider::SharedImageProvider()
72 : QQuickImageProviderWithOptions(QQuickImageProvider::Image), loader(new QuickSharedImageLoader)
73{
74}
75
76QImage SharedImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize, const QQuickImageProviderOptions &options)
77{
78 QFileInfo fi(QDir::root(), id);
79 QString path = fi.canonicalFilePath();
80 if (path.isEmpty())
81 return QImage();
82
83 QSharedImageLoader::ImageParameters params(QuickSharedImageLoader::NumImageParameters);
84 params[QuickSharedImageLoader::RequestedSize].setValue(requestedSize);
85 params[QuickSharedImageLoader::ProviderOptions].setValue(options);
86
87 QImage img = loader->load(path, params: &params);
88 if (img.isNull()) {
89 // May be sharing problem, fall back to normal local load
90 img = loader->loadFile(path, params: &params);
91 if (!img.isNull())
92 qCWarning(lcSharedImage) << "Sharing problem; loading" << id << "unshared";
93 }
94
95 //... QSize realSize = params.value(QSharedImageLoader::OriginalSize).toSize();
96 // quickpixmapcache's readImage() reports back the original size, prior to requestedSize scaling, in the *size
97 // parameter. That value is currently ignored by quick however, which only cares about the present size of the
98 // returned image. So handling and sharing of info on pre-scaled size is currently not implemented.
99 if (size) {
100 *size = img.size();
101 }
102
103 return img;
104}
105
106QT_END_NAMESPACE
107
108#include "moc_qsharedimageprovider_p.cpp"
109

source code of qtdeclarative/src/labs/sharedimage/qsharedimageprovider.cpp