/**************************************************************************** ** ** 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 #include #include #include #include #include #include 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(); } 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(); } 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"