/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module 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 "qquickpixmapcache_p.h"
#include <qquickimageprovider.h>
#include "qquickimageprovider_p.h"

#include <qqmlengine.h>
#include <private/qqmlglobal_p.h>
#include <private/qqmlengine_p.h>

#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qimage_p.h>
#include <qpa/qplatformintegration.h>

#include <QtQuick/private/qsgcontext_p.h>
#include <QtQuick/private/qsgtexturereader_p.h>

#include <QQuickWindow>
#include <QCoreApplication>
#include <QImageReader>
#include <QHash>
#include <QPixmapCache>
#include <QFile>
#include <QThread>
#include <QMutex>
#include <QMutexLocker>
#include <QBuffer>
#include <QtCore/qdebug.h>
#include <private/qobject_p.h>
#include <QQmlFile>
#include <QMetaMethod>

#if QT_CONFIG(qml_network)
#include <qqmlnetworkaccessmanagerfactory.h>
#include <QNetworkReply>
#include <QSslError>
#endif

#include <private/qquickprofiler_p.h>

#define IMAGEREQUEST_MAX_NETWORK_REQUEST_COUNT 8
#define IMAGEREQUEST_MAX_REDIRECT_RECURSION 16
#define CACHE_EXPIRE_TIME 30
#define CACHE_REMOVAL_FRACTION 4

#define PIXMAP_PROFILE(Code) Q_QUICK_PROFILE(QQuickProfiler::ProfilePixmapCache, Code)

QT_BEGIN_NAMESPACE

const QLatin1String QQuickPixmap::itemGrabberScheme = QLatin1String("itemgrabber");

#ifndef QT_NO_DEBUG
static const bool qsg_leak_check = !qEnvironmentVariableIsEmpty("QML_LEAK_CHECK");
#endif

// The cache limit describes the maximum "junk" in the cache.
static int cache_limit = 2048 * 1024; // 2048 KB cache limit for embedded in qpixmapcache.cpp

static inline QString imageProviderId(const QUrl &url)
{
    return url.host();
}

static inline QString imageId(const QUrl &url)
{
    return url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
}

QQuickDefaultTextureFactory::QQuickDefaultTextureFactory(const QImage &image)
{
    if (image.format() == QImage::Format_ARGB32_Premultiplied
            || image.format() == QImage::Format_RGB32) {
        im = image;
    } else {
        im = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
    }
    size = im.size();
}


QSGTexture *QQuickDefaultTextureFactory::createTexture(QQuickWindow *window) const
{
    QSGTexture *t = window->createTextureFromImage(im, QQuickWindow::TextureCanUseAtlas);
    static bool transient = qEnvironmentVariableIsSet("QSG_TRANSIENT_IMAGES");
    if (transient)
        const_cast<QQuickDefaultTextureFactory *>(this)->im = QImage();
    return t;
}

class QQuickPixmapReader;
class QQuickPixmapData;
class QQuickPixmapReply : public QObject
{
    Q_OBJECT
public:
    enum ReadError { NoError, Loading, Decoding };

    QQuickPixmapReply(QQuickPixmapData *);
    ~QQuickPixmapReply();

    QQuickPixmapData *data;
    QQmlEngine *engineForReader; // always access reader inside readerMutex
    QSize requestSize;
    QUrl url;

    bool loading;
    QQuickImageProviderOptions providerOptions;
    int redirectCount;

    class Event : public QEvent {
    public:
        Event(ReadError, const QString &, const QSize &, QQuickTextureFactory *factory);
        ~Event();

        ReadError error;
        QString errorString;
        QSize implicitSize;
        QQuickTextureFactory *textureFactory;
    };
    void postReply(ReadError, const QString &, const QSize &, QQuickTextureFactory *factory);


Q_SIGNALS:
    void finished();
    void downloadProgress(qint64, qint64);

protected:
    bool event(QEvent *event) override;

private:
    Q_DISABLE_COPY(QQuickPixmapReply)

public:
    static int finishedIndex;
    static int downloadProgressIndex;
};

class QQuickPixmapReaderThreadObject : public QObject {
    Q_OBJECT
public:
    QQuickPixmapReaderThreadObject(QQuickPixmapReader *);
    void processJobs();
    bool event(QEvent *e) override;
public slots:
    void asyncResponseFinished(QQuickImageResponse *response);
private slots:
    void networkRequestDone();
    void asyncResponseFinished();
private:
    QQuickPixmapReader *reader;
};

class QQuickPixmapData;
class QQuickPixmapReader : public QThread
{
    Q_OBJECT
public:
    QQuickPixmapReader(QQmlEngine *eng);
    ~QQuickPixmapReader();

    QQuickPixmapReply *getImage(QQuickPixmapData *);
    void cancel(QQuickPixmapReply *rep);

    static QQuickPixmapReader *instance(QQmlEngine *engine);
    static QQuickPixmapReader *existingInstance(QQmlEngine *engine);

protected:
    void run() override;

private:
    friend class QQuickPixmapReaderThreadObject;
    void processJobs();
    void processJob(QQuickPixmapReply *, const QUrl &, const QString &, QQuickImageProvider::ImageType, const QSharedPointer<QQuickImageProvider> &);
#if QT_CONFIG(qml_network)
    void networkRequestDone(QNetworkReply *);
#endif
    void asyncResponseFinished(QQuickImageResponse *);

    QList<QQuickPixmapReply*> jobs;
    QList<QQuickPixmapReply*> cancelled;
    QQmlEngine *engine;
    QObject *eventLoopQuitHack;

    QMutex mutex;
    QQuickPixmapReaderThreadObject *threadObject;

#if QT_CONFIG(qml_network)
    QNetworkAccessManager *networkAccessManager();
    QNetworkAccessManager *accessManager;
    QHash<QNetworkReply*,QQuickPixmapReply*> networkJobs;
#endif
    QHash<QQuickImageResponse*,QQuickPixmapReply*> asyncResponses;

    static int replyDownloadProgress;
    static int replyFinished;
    static int downloadProgress;
    static int threadNetworkRequestDone;
    static QHash<QQmlEngine *,QQuickPixmapReader*> readers;
public:
    static QMutex readerMutex;
};

class QQuickPixmapData
{
public:
    QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &s, const QQuickImageProviderOptions &po, const QString &e)
    : refCount(1), frameCount(1), frame(0), inCache(false), pixmapStatus(QQuickPixmap::Error),
      url(u), errorString(e), requestSize(s),
      providerOptions(po), appliedTransform(QQuickImageProviderOptions::UsePluginDefaultTransform),
      textureFactory(nullptr), reply(nullptr), prevUnreferenced(nullptr),
      prevUnreferencedPtr(nullptr), nextUnreferenced(nullptr)
    {
        declarativePixmaps.insert(pixmap);
    }

    QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &r, const QQuickImageProviderOptions &po, QQuickImageProviderOptions::AutoTransform aTransform, int frame=0, int frameCount=1)
    : refCount(1), frameCount(frameCount), frame(frame), inCache(false), pixmapStatus(QQuickPixmap::Loading),
      url(u), requestSize(r),
      providerOptions(po), appliedTransform(aTransform),
      textureFactory(nullptr), reply(nullptr), prevUnreferenced(nullptr), prevUnreferencedPtr(nullptr),
      nextUnreferenced(nullptr)
    {
        declarativePixmaps.insert(pixmap);
    }

    QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, QQuickTextureFactory *texture,
                     const QSize &s, const QSize &r, const QQuickImageProviderOptions &po, QQuickImageProviderOptions::AutoTransform aTransform, int frame=0, int frameCount=1)
    : refCount(1), frameCount(frameCount), frame(frame), inCache(false), pixmapStatus(QQuickPixmap::Ready),
      url(u), implicitSize(s), requestSize(r),
      providerOptions(po), appliedTransform(aTransform),
      textureFactory(texture), reply(nullptr), prevUnreferenced(nullptr),
      prevUnreferencedPtr(nullptr), nextUnreferenced(nullptr)
    {
        declarativePixmaps.insert(pixmap);
    }

    QQuickPixmapData(QQuickPixmap *pixmap, QQuickTextureFactory *texture)
    : refCount(1), frameCount(1), frame(0), inCache(false), pixmapStatus(QQuickPixmap::Ready),
      appliedTransform(QQuickImageProviderOptions::UsePluginDefaultTransform),
      textureFactory(texture), reply(nullptr), prevUnreferenced(nullptr),
      prevUnreferencedPtr(nullptr), nextUnreferenced(nullptr)
    {
        if (texture)
            requestSize = implicitSize = texture->textureSize();
        declarativePixmaps.insert(pixmap);
    }

    ~QQuickPixmapData()
    {
        while (!declarativePixmaps.isEmpty()) {
            QQuickPixmap *referencer = declarativePixmaps.first();
            declarativePixmaps.remove(referencer);
            referencer->d = nullptr;
        }
        delete textureFactory;
    }

    int cost() const;
    void addref();
    void release();
    void addToCache();
    void removeFromCache();

    uint refCount;
    int frameCount;
    int frame;

    bool inCache:1;

    QQuickPixmap::Status pixmapStatus;
    QUrl url;
    QString errorString;
    QSize implicitSize;
    QSize requestSize;
    QQuickImageProviderOptions providerOptions;
    QQuickImageProviderOptions::AutoTransform appliedTransform;

    QQuickTextureFactory *textureFactory;

    QIntrusiveList<QQuickPixmap, &QQuickPixmap::dataListNode> declarativePixmaps;
    QQuickPixmapReply *reply;

    QQuickPixmapData *prevUnreferenced;
    QQuickPixmapData**prevUnreferencedPtr;
    QQuickPixmapData *nextUnreferenced;
};

int QQuickPixmapReply::finishedIndex = -1;
int QQuickPixmapReply::downloadProgressIndex = -1;

// XXX
QHash<QQmlEngine *,QQuickPixmapReader*> QQuickPixmapReader::readers;
QMutex QQuickPixmapReader::readerMutex;

int QQuickPixmapReader::replyDownloadProgress = -1;
int QQuickPixmapReader::replyFinished = -1;
int QQuickPixmapReader::downloadProgress = -1;
int QQuickPixmapReader::threadNetworkRequestDone = -1;


void QQuickPixmapReply::postReply(ReadError error, const QString &errorString,
                                        const QSize &implicitSize, QQuickTextureFactory *factory)
{
    loading = false;
    QCoreApplication::postEvent(this, new Event(error, errorString, implicitSize, factory));
}

QQuickPixmapReply::Event::Event(ReadError e, const QString &s, const QSize &iSize, QQuickTextureFactory *factory)
    : QEvent(QEvent::User), error(e), errorString(s), implicitSize(iSize), textureFactory(factory)
{
}

QQuickPixmapReply::Event::~Event()
{
    delete textureFactory;
}

#if QT_CONFIG(qml_network)
QNetworkAccessManager *QQuickPixmapReader::networkAccessManager()
{
    if (!accessManager) {
        Q_ASSERT(threadObject);
        accessManager = QQmlEnginePrivate::get(engine)->createNetworkAccessManager(threadObject);
    }
    return accessManager;
}
#endif

static void maybeRemoveAlpha(QImage *image)
{
    // If the image
    if (image->hasAlphaChannel() && image->data_ptr()
            && !image->data_ptr()->checkForAlphaPixels()) {
        switch (image->format()) {
        case QImage::Format_RGBA8888:
        case QImage::Format_RGBA8888_Premultiplied:
            if (image->data_ptr()->convertInPlace(QImage::Format_RGBX8888, Qt::AutoColor))
                break;

            *image = image->convertToFormat(QImage::Format_RGBX8888);
            break;
        case QImage::Format_A2BGR30_Premultiplied:
            if (image->data_ptr()->convertInPlace(QImage::Format_BGR30, Qt::AutoColor))
                break;

            *image = image->convertToFormat(QImage::Format_BGR30);
            break;
        case QImage::Format_A2RGB30_Premultiplied:
            if (image->data_ptr()->convertInPlace(QImage::Format_RGB30, Qt::AutoColor))
                break;

            *image = image->convertToFormat(QImage::Format_RGB30);
            break;
        default:
            if (image->data_ptr()->convertInPlace(QImage::Format_RGB32, Qt::AutoColor))
                break;

            *image = image->convertToFormat(QImage::Format_RGB32);
            break;
        }
    }
}

static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *errorString, QSize *impsize, int *frameCount,
                      const QSize &requestSize, const QQuickImageProviderOptions &providerOptions,
                      QQuickImageProviderOptions::AutoTransform *appliedTransform = nullptr, int frame = 0)
{
    QImageReader imgio(dev);
    if (providerOptions.autoTransform() != QQuickImageProviderOptions::UsePluginDefaultTransform)
        imgio.setAutoTransform(providerOptions.autoTransform() == QQuickImageProviderOptions::ApplyTransform);
    else if (appliedTransform)
        *appliedTransform = imgio.autoTransform() ? QQuickImageProviderOptions::ApplyTransform : QQuickImageProviderOptions::DoNotApplyTransform;

    if (frame < imgio.imageCount())
        imgio.jumpToImage(frame);

    if (frameCount)
        *frameCount = imgio.imageCount();

    QSize scSize = QQuickImageProviderWithOptions::loadSize(imgio.size(), requestSize, imgio.format(), providerOptions);
    if (scSize.isValid())
        imgio.setScaledSize(scSize);

    if (impsize)
        *impsize = imgio.size();

    if (imgio.read(image)) {
        maybeRemoveAlpha(image);
        if (impsize && impsize->width() < 0)
            *impsize = image->size();
        return true;
    } else {
        if (errorString)
            *errorString = QQuickPixmap::tr("Error decoding: %1: %2").arg(url.toString())
                                .arg(imgio.errorString());
        return false;
    }
}

static QStringList fromLatin1List(const QList<QByteArray> &list)
{
    QStringList res;
    res.reserve(list.size());
    for (const QByteArray &item : list)
        res.append(QString::fromLatin1(item));
    return res;
}

class BackendSupport
{
public:
    BackendSupport()
    {
        delete QSGContext::createTextureFactoryFromImage(QImage());  // Force init of backend data
        hasOpenGL = QQuickWindow::sceneGraphBackend().isEmpty();     // i.e. default
        QList<QByteArray> list;
        if (hasOpenGL)
            list.append(QSGTextureReader::supportedFileFormats());
        list.append(QImageReader::supportedImageFormats());
        fileSuffixes = fromLatin1List(list);
    }
    bool hasOpenGL;
    QStringList fileSuffixes;
};
Q_GLOBAL_STATIC(BackendSupport, backendSupport);

static QString existingImageFileForPath(const QString &localFile)
{
    // Do nothing if given filepath exists or already has a suffix
    QFileInfo fi(localFile);
    if (!fi.suffix().isEmpty() || fi.exists())
        return localFile;

    QString tryFile = localFile + QStringLiteral(".xxxx");
    const int suffixIdx = localFile.length() + 1;
    for (const QString &suffix : backendSupport()->fileSuffixes) {
        tryFile.replace(suffixIdx, 10, suffix);
        if (QFileInfo::exists(tryFile))
            return tryFile;
    }
    return localFile;
}

QQuickPixmapReader::QQuickPixmapReader(QQmlEngine *eng)
: QThread(eng), engine(eng), threadObject(nullptr)
#if QT_CONFIG(qml_network)
, accessManager(nullptr)
#endif
{
    eventLoopQuitHack = new QObject;
    eventLoopQuitHack->moveToThread(this);
    connect(eventLoopQuitHack, SIGNAL(destroyed(QObject*)), SLOT(quit()), Qt::DirectConnection);
    start(QThread::LowestPriority);
#if !QT_CONFIG(thread)
    // call nonblocking run ourself, as nothread qthread does not
    run();
#endif
}

QQuickPixmapReader::~QQuickPixmapReader()
{
    readerMutex.lock();
    readers.remove(engine);
    readerMutex.unlock();

    mutex.lock();
    // manually cancel all outstanding jobs.
    for (QQuickPixmapReply *reply : qAsConst(jobs)) {
        if (reply->data && reply->data->reply == reply)
            reply->data->reply = nullptr;
        delete reply;
    }
    jobs.clear();
#if QT_CONFIG(qml_network)

    const auto cancelJob = [this](QQuickPixmapReply *reply) {
        if (reply->loading) {
            cancelled.append(reply);
            reply->data = nullptr;
        }
    };

    for (auto *reply : qAsConst(networkJobs))
        cancelJob(reply);

    for (auto *reply : qAsConst(asyncResponses))
        cancelJob(reply);
#endif
    if (threadObject) threadObject->processJobs();
    mutex.unlock();

    eventLoopQuitHack->deleteLater();
    wait();
}

#if QT_CONFIG(qml_network)
void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
{
    QQuickPixmapReply *job = networkJobs.take(reply);

    if (job) {
        job->redirectCount++;
        if (job->redirectCount < IMAGEREQUEST_MAX_REDIRECT_RECURSION) {
            QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
            if (redirect.isValid()) {
                QUrl url = reply->url().resolved(redirect.toUrl());
                QNetworkRequest req(url);
                req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);

                reply->deleteLater();
                reply = networkAccessManager()->get(req);

                QMetaObject::connect(reply, replyDownloadProgress, job, downloadProgress);
                QMetaObject::connect(reply, replyFinished, threadObject, threadNetworkRequestDone);

                networkJobs.insert(reply, job);
                return;
            }
        }

        QImage image;
        QQuickPixmapReply::ReadError error = QQuickPixmapReply::NoError;
        QString errorString;
        QSize readSize;
        if (reply->error()) {
            error = QQuickPixmapReply::Loading;
            errorString = reply->errorString();
        } else {
            QByteArray all = reply->readAll();
            QBuffer buff(&all);
            buff.open(QIODevice::ReadOnly);
            int frameCount;
            int const frame = job->data ? job->data->frame : 0;
            if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, &frameCount, job->requestSize, job->providerOptions, nullptr, frame))
                error = QQuickPixmapReply::Decoding;
            else if (job->data)
                job->data->frameCount = frameCount;
        }
        // send completion event to the QQuickPixmapReply
        mutex.lock();
        if (!cancelled.contains(job))
            job->postReply(error, errorString, readSize, QQuickTextureFactory::textureFactoryForImage(image));
        mutex.unlock();
    }
    reply->deleteLater();

    // kick off event loop again incase we have dropped below max request count
    threadObject->processJobs();
}
#endif // qml_network

void QQuickPixmapReader::asyncResponseFinished(QQuickImageResponse *response)
{
    QQuickPixmapReply *job = asyncResponses.take(response);

    if (job) {
        QQuickTextureFactory *t = nullptr;
        QQuickPixmapReply::ReadError error = QQuickPixmapReply::NoError;
        QString errorString;
        if (!response->errorString().isEmpty()) {
            error = QQuickPixmapReply::Loading;
            errorString = response->errorString();
        } else {
            t = response->textureFactory();
       }
        mutex.lock();
        if (!cancelled.contains(job))
            job->postReply(error, errorString, t ? t->textureSize() : QSize(), t);
        else
            delete t;
        mutex.unlock();
    }
    response->deleteLater();

    // kick off event loop again incase we have dropped below max request count
    threadObject->processJobs();
}

QQuickPixmapReaderThreadObject::QQuickPixmapReaderThreadObject(QQuickPixmapReader *i)
: reader(i)
{
}

void QQuickPixmapReaderThreadObject::processJobs()
{
    QCoreApplication::postEvent(this, new QEvent(QEvent::User));
}

bool QQuickPixmapReaderThreadObject::event(QEvent *e)
{
    if (e->type() == QEvent::User) {
        reader->processJobs();
        return true;
    } else {
        return QObject::event(e);
    }
}

void QQuickPixmapReaderThreadObject::networkRequestDone()
{
#if QT_CONFIG(qml_network)
    QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
    reader->networkRequestDone(reply);
#endif
}

void QQuickPixmapReaderThreadObject::asyncResponseFinished(QQuickImageResponse *response)
{
    reader->asyncResponseFinished(response);
}

void QQuickPixmapReaderThreadObject::asyncResponseFinished()
{
    QQuickImageResponse *response = static_cast<QQuickImageResponse *>(sender());
    asyncResponseFinished(response);
}

void QQuickPixmapReader::processJobs()
{
    QMutexLocker locker(&mutex);

    while (true) {
        if (cancelled.isEmpty() && jobs.isEmpty())
            return; // Nothing else to do

        // Clean cancelled jobs
        if (!cancelled.isEmpty()) {
#if QT_CONFIG(qml_network)
            for (int i = 0; i < cancelled.count(); ++i) {
                QQuickPixmapReply *job = cancelled.at(i);
                QNetworkReply *reply = networkJobs.key(job, 0);
                if (reply) {
                    networkJobs.remove(reply);
                    if (reply->isRunning()) {
                        // cancel any jobs already started
                        reply->close();
                    }
                } else {
                    QQuickImageResponse *asyncResponse = asyncResponses.key(job);
                    if (asyncResponse) {
                        asyncResponses.remove(asyncResponse);
                        asyncResponse->cancel();
                    }
                }
                PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(job->url));
                // deleteLater, since not owned by this thread
                job->deleteLater();
            }
            cancelled.clear();
#endif
        }

        if (!jobs.isEmpty()) {
            // Find a job we can use
            bool usableJob = false;
            for (int i = jobs.count() - 1; !usableJob && i >= 0; i--) {
                QQuickPixmapReply *job = jobs.at(i);
                const QUrl url = job->url;
                QString localFile;
                QQuickImageProvider::ImageType imageType = QQuickImageProvider::Invalid;
                QSharedPointer<QQuickImageProvider> provider;

                if (url.scheme() == QLatin1String("image")) {
                    QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine);
                    provider = enginePrivate->imageProvider(imageProviderId(url)).staticCast<QQuickImageProvider>();
                    if (provider)
                        imageType = provider->imageType();

                    usableJob = true;
                } else {
                    localFile = QQmlFile::urlToLocalFileOrQrc(url);
                    usableJob = !localFile.isEmpty()
#if QT_CONFIG(qml_network)
                            || networkJobs.count() < IMAGEREQUEST_MAX_NETWORK_REQUEST_COUNT
#endif
                            ;
                }


                if (usableJob) {
                    jobs.removeAt(i);

                    job->loading = true;

                    PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(url));

                    locker.unlock();
                    processJob(job, url, localFile, imageType, provider);
                    locker.relock();
                }
            }

            if (!usableJob)
                return;
        }
    }
}

void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &url, const QString &localFile,
                                    QQuickImageProvider::ImageType imageType, const QSharedPointer<QQuickImageProvider> &provider)
{
    // fetch
    if (url.scheme() == QLatin1String("image")) {
        // Use QQuickImageProvider
        QSize readSize;

        if (imageType == QQuickImageProvider::Invalid) {
            QString errorStr = QQuickPixmap::tr("Invalid image provider: %1").arg(url.toString());
            mutex.lock();
            if (!cancelled.contains(runningJob))
                runningJob->postReply(QQuickPixmapReply::Loading, errorStr, readSize, nullptr);
            mutex.unlock();
            return;
        }

        // This is safe because we ensure that provider does outlive providerV2 and it does not escape the function
        QQuickImageProviderWithOptions *providerV2 = QQuickImageProviderWithOptions::checkedCast(provider.get());

        switch (imageType) {
            case QQuickImageProvider::Invalid:
            {
                // Already handled
                break;
            }

            case QQuickImageProvider::Image:
            {
                QImage image;
                if (providerV2) {
                    image = providerV2->requestImage(imageId(url), &readSize, runningJob->requestSize, runningJob->providerOptions);
                } else {
                    image = provider->requestImage(imageId(url), &readSize, runningJob->requestSize);
                }
                QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
                QString errorStr;
                if (image.isNull()) {
                    errorCode = QQuickPixmapReply::Loading;
                    errorStr = QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString());
                }
                mutex.lock();
                if (!cancelled.contains(runningJob))
                    runningJob->postReply(errorCode, errorStr, readSize, QQuickTextureFactory::textureFactoryForImage(image));
                mutex.unlock();
                break;
            }

            case QQuickImageProvider::Pixmap:
            {
                QPixmap pixmap;
                if (providerV2) {
                    pixmap = providerV2->requestPixmap(imageId(url), &readSize, runningJob->requestSize, runningJob->providerOptions);
                } else {
                    pixmap = provider->requestPixmap(imageId(url), &readSize, runningJob->requestSize);
                }
                QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
                QString errorStr;
                if (pixmap.isNull()) {
                    errorCode = QQuickPixmapReply::Loading;
                    errorStr = QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString());
                }
                mutex.lock();
                if (!cancelled.contains(runningJob))
                    runningJob->postReply(errorCode, errorStr, readSize, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()));
                mutex.unlock();
                break;
            }

            case QQuickImageProvider::Texture:
            {
                QQuickTextureFactory *t;
                if (providerV2) {
                    t = providerV2->requestTexture(imageId(url), &readSize, runningJob->requestSize, runningJob->providerOptions);
                } else {
                    t = provider->requestTexture(imageId(url), &readSize, runningJob->requestSize);
                }
                QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
                QString errorStr;
                if (!t) {
                    errorCode = QQuickPixmapReply::Loading;
                    errorStr = QQuickPixmap::tr("Failed to get texture from provider: %1").arg(url.toString());
                }
                mutex.lock();
                if (!cancelled.contains(runningJob))
                    runningJob->postReply(errorCode, errorStr, readSize, t);
                else
                    delete t;
                mutex.unlock();
                break;
            }

            case QQuickImageProvider::ImageResponse:
            {
                QQuickImageResponse *response;
                if (providerV2) {
                    response = providerV2->requestImageResponse(imageId(url), runningJob->requestSize, runningJob->providerOptions);
                } else {
                    QQuickAsyncImageProvider *asyncProvider = static_cast<QQuickAsyncImageProvider*>(provider.get());
                    response = asyncProvider->requestImageResponse(imageId(url), runningJob->requestSize);
                }

                {
                    QObject::connect(response, SIGNAL(finished()), threadObject, SLOT(asyncResponseFinished()));
                    // as the response object can outlive the provider QSharedPointer, we have to extend the pointee's lifetime by that of the response
                    // we do this by capturing a copy of the QSharedPointer in a lambda, and dropping it once the lambda has been called
                    auto provider_copy = provider; // capturing provider would capture it as a const reference, and copy capture with initializer is only available in C++14
                    QObject::connect(response, &QQuickImageResponse::destroyed, response, [provider_copy]() {
                        // provider_copy will be deleted when the connection gets deleted
                    });
                }
                // Might be that the async provider was so quick it emitted the signal before we
                // could connect to it.
                if (static_cast<QQuickImageResponsePrivate*>(QObjectPrivate::get(response))->finished.loadAcquire()) {
                    QMetaObject::invokeMethod(threadObject, "asyncResponseFinished",
                                              Qt::QueuedConnection, Q_ARG(QQuickImageResponse*, response));
                }

                asyncResponses.insert(response, runningJob);
                break;
            }
        }

    } else {
        if (!localFile.isEmpty()) {
            // Image is local - load/decode immediately
            QImage image;
            QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
            QString errorStr;
            QFile f(existingImageFileForPath(localFile));
            QSize readSize;
            if (f.open(QIODevice::ReadOnly)) {
                QSGTextureReader texReader(&f, localFile);
                if (backendSupport()->hasOpenGL && texReader.isTexture()) {
                    QQuickTextureFactory *factory = texReader.read();
                    if (factory) {
                        readSize = factory->textureSize();
                    } else {
                        errorStr = QQuickPixmap::tr("Error decoding: %1").arg(url.toString());
                        if (f.fileName() != localFile)
                            errorStr += QString::fromLatin1(" (%1)").arg(f.fileName());
                        errorCode = QQuickPixmapReply::Decoding;
                    }
                    mutex.lock();
                    if (!cancelled.contains(runningJob))
                        runningJob->postReply(errorCode, errorStr, readSize, factory);
                    mutex.unlock();
                    return;
                } else {
                    int frameCount;
                    int const frame = runningJob->data ? runningJob->data->frame : 0;
                    if ( !readImage(url, &f, &image, &errorStr, &readSize, &frameCount, runningJob->requestSize, runningJob->providerOptions, nullptr, frame)) {
                        errorCode = QQuickPixmapReply::Loading;
                        if (f.fileName() != localFile)
                            errorStr += QString::fromLatin1(" (%1)").arg(f.fileName());
                    } else if (runningJob->data) {
                        runningJob->data->frameCount = frameCount;
                    }
                }
            } else {
                errorStr = QQuickPixmap::tr("Cannot open: %1").arg(url.toString());
                errorCode = QQuickPixmapReply::Loading;
            }
            mutex.lock();
            if (!cancelled.contains(runningJob))
                runningJob->postReply(errorCode, errorStr, readSize, QQuickTextureFactory::textureFactoryForImage(image));
            mutex.unlock();
        } else {
#if QT_CONFIG(qml_network)
            // Network resource
            QNetworkRequest req(url);
            req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
            QNetworkReply *reply = networkAccessManager()->get(req);

            QMetaObject::connect(reply, replyDownloadProgress, runningJob, downloadProgress);
            QMetaObject::connect(reply, replyFinished, threadObject, threadNetworkRequestDone);

            networkJobs.insert(reply, runningJob);
#else
// Silently fail if compiled with no_network
#endif
        }
    }
}

QQuickPixmapReader *QQuickPixmapReader::instance(QQmlEngine *engine)
{
    // XXX NOTE: must be called within readerMutex locking.
    QQuickPixmapReader *reader = readers.value(engine);
    if (!reader) {
        reader = new QQuickPixmapReader(engine);
        readers.insert(engine, reader);
    }

    return reader;
}

QQuickPixmapReader *QQuickPixmapReader::existingInstance(QQmlEngine *engine)
{
    // XXX NOTE: must be called within readerMutex locking.
    return readers.value(engine, 0);
}

QQuickPixmapReply *QQuickPixmapReader::getImage(QQuickPixmapData *data)
{
    mutex.lock();
    QQuickPixmapReply *reply = new QQuickPixmapReply(data);
    reply->engineForReader = engine;
    jobs.append(reply);
    // XXX
    if (threadObject) threadObject->processJobs();
    mutex.unlock();
    return reply;
}

void QQuickPixmapReader::cancel(QQuickPixmapReply *reply)
{
    mutex.lock();
    if (reply->loading) {
        cancelled.append(reply);
        reply->data = nullptr;
        // XXX
        if (threadObject) threadObject->processJobs();
    } else {
        // If loading was started (reply removed from jobs) but the reply was never processed
        // (otherwise it would have deleted itself) we need to profile an error.
        if (jobs.removeAll(reply) == 0) {
            PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(reply->url));
        }
        delete reply;
    }
    mutex.unlock();
}

void QQuickPixmapReader::run()
{
    if (replyDownloadProgress == -1) {
#if QT_CONFIG(qml_network)
        replyDownloadProgress = QMetaMethod::fromSignal(&QNetworkReply::downloadProgress).methodIndex();
        replyFinished = QMetaMethod::fromSignal(&QNetworkReply::finished).methodIndex();
        const QMetaObject *ir = &QQuickPixmapReaderThreadObject::staticMetaObject;
        threadNetworkRequestDone = ir->indexOfSlot("networkRequestDone()");
#endif
        downloadProgress = QMetaMethod::fromSignal(&QQuickPixmapReply::downloadProgress).methodIndex();
    }

    mutex.lock();
    threadObject = new QQuickPixmapReaderThreadObject(this);
    mutex.unlock();

    processJobs();
    exec();

#if QT_CONFIG(thread)
    // nothread exec is empty and returns
    delete threadObject;
    threadObject = nullptr;
#endif
}

class QQuickPixmapKey
{
public:
    const QUrl *url;
    const QSize *size;
    int frame;
    QQuickImageProviderOptions options;
};

inline bool operator==(const QQuickPixmapKey &lhs, const QQuickPixmapKey &rhs)
{
    return *lhs.size == *rhs.size && *lhs.url == *rhs.url && lhs.options == rhs.options && lhs.frame == rhs.frame;
}

inline uint qHash(const QQuickPixmapKey &key)
{
    return qHash(*key.url) ^ (key.size->width()*7) ^ (key.size->height()*17) ^ (key.frame*23) ^ (key.options.autoTransform() * 0x5c5c5c5c);
}

class QQuickPixmapStore : public QObject
{
    Q_OBJECT
public:
    QQuickPixmapStore();
    ~QQuickPixmapStore();

    void unreferencePixmap(QQuickPixmapData *);
    void referencePixmap(QQuickPixmapData *);

    void purgeCache();

protected:
    void timerEvent(QTimerEvent *) override;

public:
    QHash<QQuickPixmapKey, QQuickPixmapData *> m_cache;

private:
    void shrinkCache(int remove);

    QQuickPixmapData *m_unreferencedPixmaps;
    QQuickPixmapData *m_lastUnreferencedPixmap;

    int m_unreferencedCost;
    int m_timerId;
    bool m_destroying;
};
Q_GLOBAL_STATIC(QQuickPixmapStore, pixmapStore);


QQuickPixmapStore::QQuickPixmapStore()
    : m_unreferencedPixmaps(nullptr), m_lastUnreferencedPixmap(nullptr), m_unreferencedCost(0), m_timerId(-1), m_destroying(false)
{
}

QQuickPixmapStore::~QQuickPixmapStore()
{
    m_destroying = true;

#ifndef QT_NO_DEBUG
    int leakedPixmaps = 0;
#endif
    // Prevent unreferencePixmap() from assuming it needs to kick
    // off the cache expiry timer, as we're shrinking the cache
    // manually below after releasing all the pixmaps.
    m_timerId = -2;

    // unreference all (leaked) pixmaps
    const auto cache = m_cache; // NOTE: intentional copy (QTBUG-65077); releasing items from the cache modifies m_cache.
    for (auto *pixmap : cache) {
        int currRefCount = pixmap->refCount;
        if (currRefCount) {
#ifndef QT_NO_DEBUG
            leakedPixmaps++;
#endif
            while (currRefCount > 0) {
                pixmap->release();
                currRefCount--;
            }
        }
    }

    // free all unreferenced pixmaps
    while (m_lastUnreferencedPixmap) {
        shrinkCache(20);
    }

#ifndef QT_NO_DEBUG
    if (leakedPixmaps && qsg_leak_check)
        qDebug("Number of leaked pixmaps: %i", leakedPixmaps);
#endif
}

void QQuickPixmapStore::unreferencePixmap(QQuickPixmapData *data)
{
    Q_ASSERT(data->prevUnreferenced == nullptr);
    Q_ASSERT(data->prevUnreferencedPtr == nullptr);
    Q_ASSERT(data->nextUnreferenced == nullptr);

    data->nextUnreferenced = m_unreferencedPixmaps;
    data->prevUnreferencedPtr = &m_unreferencedPixmaps;
    if (!m_destroying) // the texture factories may have been cleaned up already.
        m_unreferencedCost += data->cost();

    m_unreferencedPixmaps = data;
    if (m_unreferencedPixmaps->nextUnreferenced) {
        m_unreferencedPixmaps->nextUnreferenced->prevUnreferenced = m_unreferencedPixmaps;
        m_unreferencedPixmaps->nextUnreferenced->prevUnreferencedPtr = &m_unreferencedPixmaps->nextUnreferenced;
    }

    if (!m_lastUnreferencedPixmap)
        m_lastUnreferencedPixmap = data;

    shrinkCache(-1); // Shrink the cache in case it has become larger than cache_limit

    if (m_timerId == -1 && m_unreferencedPixmaps
            && !m_destroying && !QCoreApplication::closingDown()) {
        m_timerId = startTimer(CACHE_EXPIRE_TIME * 1000);
    }
}

void QQuickPixmapStore::referencePixmap(QQuickPixmapData *data)
{
    Q_ASSERT(data->prevUnreferencedPtr);

    *data->prevUnreferencedPtr = data->nextUnreferenced;
    if (data->nextUnreferenced) {
        data->nextUnreferenced->prevUnreferencedPtr = data->prevUnreferencedPtr;
        data->nextUnreferenced->prevUnreferenced = data->prevUnreferenced;
    }
    if (m_lastUnreferencedPixmap == data)
        m_lastUnreferencedPixmap = data->prevUnreferenced;

    data->nextUnreferenced = nullptr;
    data->prevUnreferencedPtr = nullptr;
    data->prevUnreferenced = nullptr;

    m_unreferencedCost -= data->cost();
}

void QQuickPixmapStore::shrinkCache(int remove)
{
    while ((remove > 0 || m_unreferencedCost > cache_limit) && m_lastUnreferencedPixmap) {
        QQuickPixmapData *data = m_lastUnreferencedPixmap;
        Q_ASSERT(data->nextUnreferenced == nullptr);

        *data->prevUnreferencedPtr = nullptr;
        m_lastUnreferencedPixmap = data->prevUnreferenced;
        data->prevUnreferencedPtr = nullptr;
        data->prevUnreferenced = nullptr;

        if (!m_destroying) {
            remove -= data->cost();
            m_unreferencedCost -= data->cost();
        }
        data->removeFromCache();
        delete data;
    }
}

void QQuickPixmapStore::timerEvent(QTimerEvent *)
{
    int removalCost = m_unreferencedCost / CACHE_REMOVAL_FRACTION;

    shrinkCache(removalCost);

    if (m_unreferencedPixmaps == nullptr) {
        killTimer(m_timerId);
        m_timerId = -1;
    }
}

void QQuickPixmapStore::purgeCache()
{
    shrinkCache(m_unreferencedCost);
}

void QQuickPixmap::purgeCache()
{
    pixmapStore()->purgeCache();
}

QQuickPixmapReply::QQuickPixmapReply(QQuickPixmapData *d)
: data(d), engineForReader(nullptr), requestSize(d->requestSize), url(d->url), loading(false), providerOptions(d->providerOptions), redirectCount(0)
{
    if (finishedIndex == -1) {
        finishedIndex = QMetaMethod::fromSignal(&QQuickPixmapReply::finished).methodIndex();
        downloadProgressIndex = QMetaMethod::fromSignal(&QQuickPixmapReply::downloadProgress).methodIndex();
    }
}

QQuickPixmapReply::~QQuickPixmapReply()
{
    // note: this->data->reply must be set to zero if this->data->reply == this
    // but it must be done within mutex locking, to be guaranteed to be safe.
}

bool QQuickPixmapReply::event(QEvent *event)
{
    if (event->type() == QEvent::User) {

        if (data) {
            Event *de = static_cast<Event *>(event);
            data->pixmapStatus = (de->error == NoError) ? QQuickPixmap::Ready : QQuickPixmap::Error;
            if (data->pixmapStatus == QQuickPixmap::Ready) {
                data->textureFactory = de->textureFactory;
                de->textureFactory = nullptr;
                data->implicitSize = de->implicitSize;
                PIXMAP_PROFILE(pixmapLoadingFinished(data->url,
                        data->textureFactory != nullptr && data->textureFactory->textureSize().isValid() ?
                        data->textureFactory->textureSize() :
                        (data->requestSize.isValid() ? data->requestSize : data->implicitSize)));
            } else {
                PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(data->url));
                data->errorString = de->errorString;
                data->removeFromCache(); // We don't continue to cache error'd pixmaps
            }

            data->reply = nullptr;
            emit finished();
        } else {
            PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(url));
        }

        delete this;
        return true;
    } else {
        return QObject::event(event);
    }
}

int QQuickPixmapData::cost() const
{
    if (textureFactory)
        return textureFactory->textureByteCount();
    return 0;
}

void QQuickPixmapData::addref()
{
    ++refCount;
    PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapReferenceCountChanged>(url, refCount));
    if (prevUnreferencedPtr)
        pixmapStore()->referencePixmap(this);
}

void QQuickPixmapData::release()
{
    Q_ASSERT(refCount > 0);
    --refCount;
    PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapReferenceCountChanged>(url, refCount));
    if (refCount == 0) {
        if (reply) {
            QQuickPixmapReply *cancelReply = reply;
            reply->data = nullptr;
            reply = nullptr;
            QQuickPixmapReader::readerMutex.lock();
            QQuickPixmapReader *reader = QQuickPixmapReader::existingInstance(cancelReply->engineForReader);
            if (reader)
                reader->cancel(cancelReply);
            QQuickPixmapReader::readerMutex.unlock();
        }

        if (pixmapStatus == QQuickPixmap::Ready) {
            if (inCache)
                pixmapStore()->unreferencePixmap(this);
            else
                delete this;
        } else {
            removeFromCache();
            delete this;
        }
    }
}

void QQuickPixmapData::addToCache()
{
    if (!inCache) {
        QQuickPixmapKey key = { &url, &requestSize, frame, providerOptions };
        pixmapStore()->m_cache.insert(key, this);
        inCache = true;
        PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>(
                url, pixmapStore()->m_cache.count()));
    }
}

void QQuickPixmapData::removeFromCache()
{
    if (inCache) {
        QQuickPixmapKey key = { &url, &requestSize, frame, providerOptions };
        pixmapStore()->m_cache.remove(key);
        inCache = false;
        PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>(
                url, pixmapStore()->m_cache.count()));
    }
}

static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, QQmlEngine *engine, const QUrl &url, const QSize &requestSize, const QQuickImageProviderOptions &providerOptions, int frame, bool *ok)
{
    if (url.scheme() == QLatin1String("image")) {
        QSize readSize;

        QQuickImageProvider::ImageType imageType = QQuickImageProvider::Invalid;
        QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine);
        QSharedPointer<QQuickImageProvider> provider = enginePrivate->imageProvider(imageProviderId(url)).dynamicCast<QQuickImageProvider>();
        // it is safe to use get() as providerV2 does not escape and is outlived by provider
        QQuickImageProviderWithOptions *providerV2 = QQuickImageProviderWithOptions::checkedCast(provider.get());
        if (provider)
            imageType = provider->imageType();

        switch (imageType) {
            case QQuickImageProvider::Invalid:
                return new QQuickPixmapData(declarativePixmap, url, requestSize, providerOptions,
                    QQuickPixmap::tr("Invalid image provider: %1").arg(url.toString()));
            case QQuickImageProvider::Texture:
            {
                QQuickTextureFactory *texture = providerV2 ? providerV2->requestTexture(imageId(url), &readSize, requestSize, providerOptions)
                                                           : provider->requestTexture(imageId(url), &readSize, requestSize);
                if (texture) {
                    *ok = true;
                    return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
                }
                break;
            }

            case QQuickImageProvider::Image:
            {
                QImage image = providerV2 ? providerV2->requestImage(imageId(url), &readSize, requestSize, providerOptions)
                                          : provider->requestImage(imageId(url), &readSize, requestSize);
                if (!image.isNull()) {
                    *ok = true;
                    return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
                }
                break;
            }
            case QQuickImageProvider::Pixmap:
            {
                QPixmap pixmap = providerV2 ? providerV2->requestPixmap(imageId(url), &readSize, requestSize, providerOptions)
                                            : provider->requestPixmap(imageId(url), &readSize, requestSize);
                if (!pixmap.isNull()) {
                    *ok = true;
                    return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()), readSize, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
                }
                break;
            }
            case QQuickImageProvider::ImageResponse:
            {
                // Fall through, ImageResponse providers never get here
                Q_ASSERT(imageType != QQuickImageProvider::ImageResponse && "Sync call to ImageResponse provider");
            }
        }

        // provider has bad image type, or provider returned null image
        return new QQuickPixmapData(declarativePixmap, url, requestSize, providerOptions,
            QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString()));
    }

    QString localFile = QQmlFile::urlToLocalFileOrQrc(url);
    if (localFile.isEmpty())
        return nullptr;

    QFile f(existingImageFileForPath(localFile));
    QSize readSize;
    QString errorString;

    if (f.open(QIODevice::ReadOnly)) {
        QSGTextureReader texReader(&f, localFile);
        if (backendSupport()->hasOpenGL && texReader.isTexture()) {
            QQuickTextureFactory *factory = texReader.read();
            if (factory) {
                *ok = true;
                return new QQuickPixmapData(declarativePixmap, url, factory, factory->textureSize(), requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame);
            } else {
                errorString = QQuickPixmap::tr("Error decoding: %1").arg(url.toString());
                if (f.fileName() != localFile)
                    errorString += QString::fromLatin1(" (%1)").arg(f.fileName());
            }
        } else {
            QImage image;
            QQuickImageProviderOptions::AutoTransform appliedTransform = providerOptions.autoTransform();
            int frameCount;
            if (readImage(url, &f, &image, &errorString, &readSize, &frameCount, requestSize, providerOptions, &appliedTransform, frame)) {
                *ok = true;
                return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, appliedTransform, frame, frameCount);
            } else if (f.fileName() != localFile) {
                errorString += QString::fromLatin1(" (%1)").arg(f.fileName());
            }
        }
    } else {
        errorString = QQuickPixmap::tr("Cannot open: %1").arg(url.toString());
    }
    return new QQuickPixmapData(declarativePixmap, url, requestSize, providerOptions, errorString);
}


struct QQuickPixmapNull {
    QUrl url;
    QSize size;
};
Q_GLOBAL_STATIC(QQuickPixmapNull, nullPixmap);

QQuickPixmap::QQuickPixmap()
: d(nullptr)
{
}

QQuickPixmap::QQuickPixmap(QQmlEngine *engine, const QUrl &url)
: d(nullptr)
{
    load(engine, url);
}

QQuickPixmap::QQuickPixmap(QQmlEngine *engine, const QUrl &url, const QSize &size)
: d(nullptr)
{
    load(engine, url, size);
}

QQuickPixmap::QQuickPixmap(const QUrl &url, const QImage &image)
{
    d = new QQuickPixmapData(this, url, new QQuickDefaultTextureFactory(image), image.size(), QSize(), QQuickImageProviderOptions(), QQuickImageProviderOptions::UsePluginDefaultTransform);
    d->addToCache();
}

QQuickPixmap::~QQuickPixmap()
{
    if (d) {
        d->declarativePixmaps.remove(this);
        d->release();
        d = nullptr;
    }
}

bool QQuickPixmap::isNull() const
{
    return d == nullptr;
}

bool QQuickPixmap::isReady() const
{
    return status() == Ready;
}

bool QQuickPixmap::isError() const
{
    return status() == Error;
}

bool QQuickPixmap::isLoading() const
{
    return status() == Loading;
}

QString QQuickPixmap::error() const
{
    if (d)
        return d->errorString;
    else
        return QString();
}

QQuickPixmap::Status QQuickPixmap::status() const
{
    if (d)
        return d->pixmapStatus;
    else
        return Null;
}

const QUrl &QQuickPixmap::url() const
{
    if (d)
        return d->url;
    else
        return nullPixmap()->url;
}

const QSize &QQuickPixmap::implicitSize() const
{
    if (d)
        return d->implicitSize;
    else
        return nullPixmap()->size;
}

const QSize &QQuickPixmap::requestSize() const
{
    if (d)
        return d->requestSize;
    else
        return nullPixmap()->size;
}

QQuickImageProviderOptions::AutoTransform QQuickPixmap::autoTransform() const
{
    if (d)
        return d->appliedTransform;
    else
        return QQuickImageProviderOptions::UsePluginDefaultTransform;
}

int QQuickPixmap::frameCount() const
{
    if (d)
        return d->frameCount;
    return 0;
}

QQuickTextureFactory *QQuickPixmap::textureFactory() const
{
    if (d)
        return d->textureFactory;

    return nullptr;
}

QImage QQuickPixmap::image() const
{
    if (d && d->textureFactory)
        return d->textureFactory->image();
    return QImage();
}

void QQuickPixmap::setImage(const QImage &p)
{
    clear();

    if (!p.isNull())
        d = new QQuickPixmapData(this, QQuickTextureFactory::textureFactoryForImage(p));
}

void QQuickPixmap::setPixmap(const QQuickPixmap &other)
{
    clear();

    if (other.d) {
        d = other.d;
        d->addref();
        d->declarativePixmaps.insert(this);
    }
}

int QQuickPixmap::width() const
{
    if (d && d->textureFactory)
        return d->textureFactory->textureSize().width();
    else
        return 0;
}

int QQuickPixmap::height() const
{
    if (d && d->textureFactory)
        return d->textureFactory->textureSize().height();
    else
        return 0;
}

QRect QQuickPixmap::rect() const
{
    if (d && d->textureFactory)
        return QRect(QPoint(), d->textureFactory->textureSize());
    else
        return QRect();
}

void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url)
{
    load(engine, url, QSize(), QQuickPixmap::Cache);
}

void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, QQuickPixmap::Options options)
{
    load(engine, url, QSize(), options);
}

void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &size)
{
    load(engine, url, size, QQuickPixmap::Cache);
}

void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &requestSize, QQuickPixmap::Options options)
{
    load(engine, url, requestSize, options, QQuickImageProviderOptions());
}

void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &requestSize, QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame, int frameCount)
{
    if (d) {
        d->declarativePixmaps.remove(this);
        d->release();
        d = nullptr;
    }

    QQuickPixmapKey key = { &url, &requestSize, frame, providerOptions };
    QQuickPixmapStore *store = pixmapStore();

    QHash<QQuickPixmapKey, QQuickPixmapData *>::Iterator iter = store->m_cache.end();

    // If Cache is disabled, the pixmap will always be loaded, even if there is an existing
    // cached version. Unless it's an itemgrabber url, since the cache is used to pass
    // the result between QQuickItemGrabResult and QQuickImage.
    if (url.scheme() == itemGrabberScheme) {
        QSize dummy;
        if (requestSize != dummy)
            qWarning() << "Ignoring sourceSize request for image url that came from grabToImage. Use the targetSize parameter of the grabToImage() function instead.";
        const QQuickPixmapKey grabberKey = { &url, &dummy, 0, QQuickImageProviderOptions() };
        iter = store->m_cache.find(grabberKey);
    } else if (options & QQuickPixmap::Cache)
        iter = store->m_cache.find(key);

    if (iter == store->m_cache.end()) {
        if (url.scheme() == QLatin1String("image")) {
            QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine);
            if (auto provider = enginePrivate->imageProvider(imageProviderId(url)).staticCast<QQuickImageProvider>()) {
                const bool threadedPixmaps = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedPixmaps);
                if (!threadedPixmaps && provider->imageType() == QQuickImageProvider::Pixmap) {
                    // pixmaps can only be loaded synchronously
                    options &= ~QQuickPixmap::Asynchronous;
                } else if (provider->flags() & QQuickImageProvider::ForceAsynchronousImageLoading) {
                    options |= QQuickPixmap::Asynchronous;
                }
            }
        }

        if (!(options & QQuickPixmap::Asynchronous)) {
            bool ok = false;
            PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(url));
            d = createPixmapDataSync(this, engine, url, requestSize, providerOptions, frame, &ok);
            if (ok) {
                PIXMAP_PROFILE(pixmapLoadingFinished(url, QSize(width(), height())));
                if (options & QQuickPixmap::Cache)
                    d->addToCache();
                return;
            }
            if (d) { // loadable, but encountered error while loading
                PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(url));
                return;
            }
        }

        if (!engine)
            return;


        d = new QQuickPixmapData(this, url, requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform, frame, frameCount);
        if (options & QQuickPixmap::Cache)
            d->addToCache();

        QQuickPixmapReader::readerMutex.lock();
        d->reply = QQuickPixmapReader::instance(engine)->getImage(d);
        QQuickPixmapReader::readerMutex.unlock();
    } else {
        d = *iter;
        d->addref();
        d->declarativePixmaps.insert(this);
    }
}

void QQuickPixmap::clear()
{
    if (d) {
        d->declarativePixmaps.remove(this);
        d->release();
        d = nullptr;
    }
}

void QQuickPixmap::clear(QObject *obj)
{
    if (d) {
        if (d->reply)
            QObject::disconnect(d->reply, nullptr, obj, nullptr);
        d->declarativePixmaps.remove(this);
        d->release();
        d = nullptr;
    }
}

bool QQuickPixmap::isCached(const QUrl &url, const QSize &requestSize, const int frame, const QQuickImageProviderOptions &options)
{
    QQuickPixmapKey key = { &url, &requestSize, frame, options };
    QQuickPixmapStore *store = pixmapStore();

    return store->m_cache.contains(key);
}

bool QQuickPixmap::connectFinished(QObject *object, const char *method)
{
    if (!d || !d->reply) {
        qWarning("QQuickPixmap: connectFinished() called when not loading.");
        return false;
    }

    return QObject::connect(d->reply, SIGNAL(finished()), object, method);
}

bool QQuickPixmap::connectFinished(QObject *object, int method)
{
    if (!d || !d->reply) {
        qWarning("QQuickPixmap: connectFinished() called when not loading.");
        return false;
    }

    return QMetaObject::connect(d->reply, QQuickPixmapReply::finishedIndex, object, method);
}

bool QQuickPixmap::connectDownloadProgress(QObject *object, const char *method)
{
    if (!d || !d->reply) {
        qWarning("QQuickPixmap: connectDownloadProgress() called when not loading.");
        return false;
    }

    return QObject::connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), object, method);
}

bool QQuickPixmap::connectDownloadProgress(QObject *object, int method)
{
    if (!d || !d->reply) {
        qWarning("QQuickPixmap: connectDownloadProgress() called when not loading.");
        return false;
    }

    return QMetaObject::connect(d->reply, QQuickPixmapReply::downloadProgressIndex, object, method);
}

QT_END_NAMESPACE

#include <qquickpixmapcache.moc>

#include "moc_qquickpixmapcache_p.cpp"
