diff options
Diffstat (limited to 'src/labs/sharedimage/qsharedimageprovider.cpp')
-rw-r--r-- | src/labs/sharedimage/qsharedimageprovider.cpp | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/labs/sharedimage/qsharedimageprovider.cpp b/src/labs/sharedimage/qsharedimageprovider.cpp new file mode 100644 index 0000000000..33f72447e3 --- /dev/null +++ b/src/labs/sharedimage/qsharedimageprovider.cpp @@ -0,0 +1,108 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include <qsharedimageprovider_p.h> +#include <private/qquickpixmap_p.h> +#include <private/qimage_p.h> +#include <QImageReader> +#include <QFileInfo> +#include <QDir> + +Q_DECLARE_METATYPE(QQuickImageProviderOptions) + +QT_BEGIN_NAMESPACE + +QuickSharedImageLoader::QuickSharedImageLoader(QObject *parent) : QSharedImageLoader(parent) {} + +QImage QuickSharedImageLoader::loadFile(const QString &path, ImageParameters *params) +{ + 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->size() > OriginalSize) + params->replace(OriginalSize, realSize); + + return image; +} + +QString QuickSharedImageLoader::key(const QString &path, ImageParameters *params) +{ + 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; +} + +QT_END_NAMESPACE + +#include "moc_qsharedimageprovider_p.cpp" |