blob: aad6ea3b78902f0ed94a369ffb06e383e73a4c0d [file] [log] [blame]
/****************************************************************************
**
** 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, &params);
if (img.isNull()) {
// May be sharing problem, fall back to normal local load
img = loader->loadFile(path, &params);
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"