| /**************************************************************************** |
| ** |
| ** Copyright (C) 2017 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the plugins of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Lesser General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Lesser |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
| ** packaging of this file. Please review the following information to |
| ** ensure the GNU Lesser General Public License version 3 requirements |
| ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 2.0 or (at your option) the GNU General |
| ** Public license version 3 or any later version approved by the KDE Free |
| ** Qt Foundation. The licenses are as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
| ** https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include <sharedimageprovider.h> |
| #include <qsharedimageloader_p.h> |
| #include <private/qquickpixmapcache_p.h> |
| #include <private/qimage_p.h> |
| #include <QImageReader> |
| #include <QFileInfo> |
| #include <QDir> |
| |
| Q_DECLARE_METATYPE(QQuickImageProviderOptions) |
| |
| class QuickSharedImageLoader : public QSharedImageLoader |
| { |
| Q_OBJECT |
| friend class SharedImageProvider; |
| |
| public: |
| enum ImageParameter { |
| OriginalSize = 0, |
| RequestedSize, |
| ProviderOptions, |
| NumImageParameters |
| }; |
| |
| QuickSharedImageLoader(QObject *parent = nullptr) |
| : QSharedImageLoader(parent) |
| { |
| } |
| |
| protected: |
| QImage loadFile(const QString &path, ImageParameters *params) override |
| { |
| QImageReader imgio(path); |
| QSize realSize = imgio.size(); |
| QSize requestSize; |
| QQuickImageProviderOptions options; |
| if (params) { |
| requestSize = params->value(RequestedSize).toSize(); |
| options = params->value(ProviderOptions).value<QQuickImageProviderOptions>(); |
| } |
| |
| QSize scSize = QQuickImageProviderWithOptions::loadSize(imgio.size(), requestSize, imgio.format(), options); |
| |
| if (scSize.isValid()) |
| imgio.setScaledSize(scSize); |
| |
| QImage image; |
| if (imgio.read(&image)) { |
| if (realSize.isEmpty()) |
| realSize = image.size(); |
| // Make sure we have acceptable format for texture uploader, or it will convert & lose sharing |
| // This mimics the testing & conversion normally done by the quick pixmapcache & texturefactory |
| if (image.format() != QImage::Format_RGB32 && image.format() != QImage::Format_ARGB32_Premultiplied) { |
| QImage::Format newFmt = QImage::Format_RGB32; |
| if (image.hasAlphaChannel() && image.data_ptr()->checkForAlphaPixels()) |
| newFmt = QImage::Format_ARGB32_Premultiplied; |
| qCDebug(lcSharedImage) << "Convert on load from format" << image.format() << "to" << newFmt; |
| image = image.convertToFormat(newFmt); |
| } |
| } |
| |
| if (params && params->count() > OriginalSize) |
| params->replace(OriginalSize, realSize); |
| |
| return image; |
| } |
| |
| QString key(const QString &path, ImageParameters *params) override |
| { |
| QSize reqSz; |
| QQuickImageProviderOptions opts; |
| if (params) { |
| reqSz = params->value(RequestedSize).toSize(); |
| opts = params->value(ProviderOptions).value<QQuickImageProviderOptions>(); |
| } |
| if (!reqSz.isValid()) |
| return path; |
| int aspect = opts.preserveAspectRatioCrop() || opts.preserveAspectRatioFit() ? 1 : 0; |
| |
| QString key = path + QStringLiteral("_%1x%2_%3").arg(reqSz.width()).arg(reqSz.height()).arg(aspect); |
| qCDebug(lcSharedImage) << "KEY:" << key; |
| return key; |
| } |
| }; |
| |
| |
| SharedImageProvider::SharedImageProvider() |
| : QQuickImageProviderWithOptions(QQuickImageProvider::Image), loader(new QuickSharedImageLoader) |
| { |
| } |
| |
| QImage SharedImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize, const QQuickImageProviderOptions &options) |
| { |
| QFileInfo fi(QDir::root(), id); |
| QString path = fi.canonicalFilePath(); |
| if (path.isEmpty()) |
| return QImage(); |
| |
| QSharedImageLoader::ImageParameters params(QuickSharedImageLoader::NumImageParameters); |
| params[QuickSharedImageLoader::RequestedSize].setValue(requestedSize); |
| params[QuickSharedImageLoader::ProviderOptions].setValue(options); |
| |
| QImage img = loader->load(path, ¶ms); |
| if (img.isNull()) { |
| // May be sharing problem, fall back to normal local load |
| img = loader->loadFile(path, ¶ms); |
| if (!img.isNull()) |
| qCWarning(lcSharedImage) << "Sharing problem; loading" << id << "unshared"; |
| } |
| |
| //... QSize realSize = params.value(QSharedImageLoader::OriginalSize).toSize(); |
| // quickpixmapcache's readImage() reports back the original size, prior to requestedSize scaling, in the *size |
| // parameter. That value is currently ignored by quick however, which only cares about the present size of the |
| // returned image. So handling and sharing of info on pre-scaled size is currently not implemented. |
| if (size) { |
| *size = img.size(); |
| } |
| |
| return img; |
| } |
| |
| #include "sharedimageprovider.moc" |