aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/util/qquickpixmapcache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/util/qquickpixmapcache.cpp')
-rw-r--r--src/quick/util/qquickpixmapcache.cpp104
1 files changed, 68 insertions, 36 deletions
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index 810629cdb6..f36d06d00d 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -131,15 +131,17 @@ public:
QUrl url;
bool loading;
+ AutoTransform autoTransform;
int redirectCount;
class Event : public QEvent {
public:
- Event(ReadError, const QString &, const QSize &, QQuickTextureFactory *factory);
+ Event(ReadError, const QString &, const QSize &, AutoTransform, QQuickTextureFactory *factory);
ReadError error;
QString errorString;
QSize implicitSize;
+ AutoTransform autoTransform;
QQuickTextureFactory *textureFactory;
};
void postReply(ReadError, const QString &, const QSize &, QQuickTextureFactory *factory);
@@ -193,7 +195,7 @@ protected:
private:
friend class QQuickPixmapReaderThreadObject;
void processJobs();
- void processJob(QQuickPixmapReply *, const QUrl &, const QString &, QQuickImageProvider::ImageType, QQuickImageProvider *);
+ void processJob(QQuickPixmapReply *, const QUrl &, const QString &, AutoTransform, QQuickImageProvider::ImageType, QQuickImageProvider *);
void networkRequestDone(QNetworkReply *);
void asyncResponseFinished(QQuickImageResponse *);
@@ -224,25 +226,32 @@ public:
class QQuickPixmapData
{
public:
- QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &s, const QString &e)
+ QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &s, AutoTransform transform, const QString &e)
: refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Error),
- url(u), errorString(e), requestSize(s), textureFactory(0), reply(0), prevUnreferenced(0),
+ url(u), errorString(e), requestSize(s),
+ requestedTransform(transform), appliedTransform(UsePluginDefault),
+ textureFactory(0), reply(0), prevUnreferenced(0),
prevUnreferencedPtr(0), nextUnreferenced(0)
{
declarativePixmaps.insert(pixmap);
}
- QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &r)
+ QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &r, AutoTransform rTransform, AutoTransform aTransform)
: refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Loading),
- url(u), requestSize(r), textureFactory(0), reply(0), prevUnreferenced(0), prevUnreferencedPtr(0),
+ url(u), requestSize(r),
+ requestedTransform(rTransform), appliedTransform(aTransform),
+ textureFactory(0), reply(0), prevUnreferenced(0), prevUnreferencedPtr(0),
nextUnreferenced(0)
{
declarativePixmaps.insert(pixmap);
}
- QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, QQuickTextureFactory *texture, const QSize &s, const QSize &r)
+ QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, QQuickTextureFactory *texture,
+ const QSize &s, const QSize &r, AutoTransform rTransform, AutoTransform aTransform)
: refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Ready),
- url(u), implicitSize(s), requestSize(r), textureFactory(texture), reply(0), prevUnreferenced(0),
+ url(u), implicitSize(s), requestSize(r),
+ requestedTransform(rTransform), appliedTransform(aTransform),
+ textureFactory(texture), reply(0), prevUnreferenced(0),
prevUnreferencedPtr(0), nextUnreferenced(0)
{
declarativePixmaps.insert(pixmap);
@@ -250,6 +259,7 @@ public:
QQuickPixmapData(QQuickPixmap *pixmap, QQuickTextureFactory *texture)
: refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Ready),
+ requestedTransform(UsePluginDefault), appliedTransform(UsePluginDefault),
textureFactory(texture), reply(0), prevUnreferenced(0),
prevUnreferencedPtr(0), nextUnreferenced(0)
{
@@ -283,6 +293,8 @@ public:
QString errorString;
QSize implicitSize;
QSize requestSize;
+ AutoTransform requestedTransform;
+ AutoTransform appliedTransform;
QQuickTextureFactory *textureFactory;
@@ -311,11 +323,11 @@ void QQuickPixmapReply::postReply(ReadError error, const QString &errorString,
const QSize &implicitSize, QQuickTextureFactory *factory)
{
loading = false;
- QCoreApplication::postEvent(this, new Event(error, errorString, implicitSize, factory));
+ QCoreApplication::postEvent(this, new Event(error, errorString, implicitSize, autoTransform, 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(ReadError e, const QString &s, const QSize &iSize, AutoTransform iTransformed, QQuickTextureFactory *factory)
+ : QEvent(QEvent::User), error(e), errorString(s), implicitSize(iSize), autoTransform(iTransformed), textureFactory(factory)
{
}
@@ -352,9 +364,13 @@ static void maybeRemoveAlpha(QImage *image)
}
static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *errorString, QSize *impsize,
- const QSize &requestSize)
+ const QSize &requestSize, AutoTransform &autoTransform)
{
QImageReader imgio(dev);
+ if (autoTransform != UsePluginDefault)
+ imgio.setAutoTransform(autoTransform == ApplyTransform);
+ else
+ autoTransform = imgio.autoTransform() ? ApplyTransform : DoNotApplyTransform;
const bool force_scale = imgio.format() == "svg" || imgio.format() == "svgz";
@@ -464,7 +480,7 @@ void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
QByteArray all = reply->readAll();
QBuffer buff(&all);
buff.open(QIODevice::ReadOnly);
- if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, job->requestSize))
+ if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, job->requestSize, job->autoTransform))
error = QQuickPixmapReply::Decoding;
}
// send completion event to the QQuickPixmapReply
@@ -599,8 +615,9 @@ void QQuickPixmapReader::processJobs()
PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(url));
+ AutoTransform autoTransform = job->autoTransform;
locker.unlock();
- processJob(job, url, localFile, imageType, provider);
+ processJob(job, url, localFile, autoTransform, imageType, provider);
locker.relock();
}
}
@@ -612,7 +629,7 @@ void QQuickPixmapReader::processJobs()
}
void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &url, const QString &localFile,
- QQuickImageProvider::ImageType imageType, QQuickImageProvider *provider)
+ AutoTransform autoTransform, QQuickImageProvider::ImageType imageType, QQuickImageProvider *provider)
{
// fetch
if (url.scheme() == QLatin1String("image")) {
@@ -701,7 +718,7 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u
QFile f(localFile);
QSize readSize;
if (f.open(QIODevice::ReadOnly)) {
- if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->requestSize))
+ if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->requestSize, autoTransform))
errorCode = QQuickPixmapReply::Loading;
} else {
errorStr = QQuickPixmap::tr("Cannot open: %1").arg(url.toString());
@@ -800,16 +817,17 @@ class QQuickPixmapKey
public:
const QUrl *url;
const QSize *size;
+ AutoTransform autoTransform;
};
inline bool operator==(const QQuickPixmapKey &lhs, const QQuickPixmapKey &rhs)
{
- return *lhs.size == *rhs.size && *lhs.url == *rhs.url;
+ return *lhs.size == *rhs.size && *lhs.url == *rhs.url && lhs.autoTransform == rhs.autoTransform;
}
inline uint qHash(const QQuickPixmapKey &key)
{
- return qHash(*key.url) ^ key.size->width() ^ key.size->height();
+ return qHash(*key.url) ^ (key.size->width()*7) ^ (key.size->height()*17) ^ (key.autoTransform * 0x5c5c5c5c);
}
class QQuickPixmapStore : public QObject
@@ -977,7 +995,7 @@ void QQuickPixmap::purgeCache()
}
QQuickPixmapReply::QQuickPixmapReply(QQuickPixmapData *d)
-: data(d), engineForReader(0), requestSize(d->requestSize), url(d->url), loading(false), redirectCount(0)
+: data(d), engineForReader(0), requestSize(d->requestSize), url(d->url), loading(false), autoTransform(d->appliedTransform), redirectCount(0)
{
if (finishedIndex == -1) {
finishedIndex = QMetaMethod::fromSignal(&QQuickPixmapReply::finished).methodIndex();
@@ -1001,6 +1019,7 @@ bool QQuickPixmapReply::event(QEvent *event)
if (data->pixmapStatus == QQuickPixmap::Ready) {
data->textureFactory = de->textureFactory;
data->implicitSize = de->implicitSize;
+ data->appliedTransform = de->autoTransform;
PIXMAP_PROFILE(pixmapLoadingFinished(data->url,
data->textureFactory != 0 && data->textureFactory->textureSize().isValid() ?
data->textureFactory->textureSize() :
@@ -1071,7 +1090,7 @@ void QQuickPixmapData::release()
void QQuickPixmapData::addToCache()
{
if (!inCache) {
- QQuickPixmapKey key = { &url, &requestSize };
+ QQuickPixmapKey key = { &url, &requestSize, requestedTransform };
pixmapStore()->m_cache.insert(key, this);
inCache = true;
PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>(
@@ -1082,7 +1101,7 @@ void QQuickPixmapData::addToCache()
void QQuickPixmapData::removeFromCache()
{
if (inCache) {
- QQuickPixmapKey key = { &url, &requestSize };
+ QQuickPixmapKey key = { &url, &requestSize, requestedTransform };
pixmapStore()->m_cache.remove(key);
inCache = false;
PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>(
@@ -1090,7 +1109,7 @@ void QQuickPixmapData::removeFromCache()
}
}
-static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, QQmlEngine *engine, const QUrl &url, const QSize &requestSize, bool *ok)
+static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, QQmlEngine *engine, const QUrl &url, const QSize &requestSize, AutoTransform autoTransform, bool *ok)
{
if (url.scheme() == QLatin1String("image")) {
QSize readSize;
@@ -1102,14 +1121,14 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
switch (imageType) {
case QQuickImageProvider::Invalid:
- return new QQuickPixmapData(declarativePixmap, url, requestSize,
+ return new QQuickPixmapData(declarativePixmap, url, requestSize, autoTransform,
QQuickPixmap::tr("Invalid image provider: %1").arg(url.toString()));
case QQuickImageProvider::Texture:
{
QQuickTextureFactory *texture = provider->requestTexture(imageId(url), &readSize, requestSize);
if (texture) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestSize);
+ return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestSize, autoTransform, UsePluginDefault);
}
}
@@ -1118,7 +1137,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
QImage image = provider->requestImage(imageId(url), &readSize, requestSize);
if (!image.isNull()) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, autoTransform, UsePluginDefault);
}
}
case QQuickImageProvider::Pixmap:
@@ -1126,7 +1145,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
QPixmap pixmap = provider->requestPixmap(imageId(url), &readSize, requestSize);
if (!pixmap.isNull()) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()), readSize, requestSize);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()), readSize, requestSize, autoTransform, UsePluginDefault);
}
}
case QQuickImageProvider::ImageResponse:
@@ -1137,7 +1156,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
}
// provider has bad image type, or provider returned null image
- return new QQuickPixmapData(declarativePixmap, url, requestSize,
+ return new QQuickPixmapData(declarativePixmap, url, requestSize, autoTransform,
QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString()));
}
@@ -1151,17 +1170,17 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
if (f.open(QIODevice::ReadOnly)) {
QImage image;
-
- if (readImage(url, &f, &image, &errorString, &readSize, requestSize)) {
+ AutoTransform appliedTransform = autoTransform;
+ if (readImage(url, &f, &image, &errorString, &readSize, requestSize, appliedTransform)) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, autoTransform, appliedTransform);
}
errorString = QQuickPixmap::tr("Invalid image data: %1").arg(url.toString());
} else {
errorString = QQuickPixmap::tr("Cannot open: %1").arg(url.toString());
}
- return new QQuickPixmapData(declarativePixmap, url, requestSize, errorString);
+ return new QQuickPixmapData(declarativePixmap, url, requestSize, autoTransform, errorString);
}
@@ -1190,7 +1209,7 @@ QQuickPixmap::QQuickPixmap(QQmlEngine *engine, const QUrl &url, const QSize &siz
QQuickPixmap::QQuickPixmap(const QUrl &url, const QImage &image)
{
- d = new QQuickPixmapData(this, url, new QQuickDefaultTextureFactory(image), image.size(), QSize());
+ d = new QQuickPixmapData(this, url, new QQuickDefaultTextureFactory(image), image.size(), QSize(), UsePluginDefault, UsePluginDefault);
d->addToCache();
}
@@ -1263,6 +1282,14 @@ const QSize &QQuickPixmap::requestSize() const
return nullPixmap()->size;
}
+AutoTransform QQuickPixmap::autoTransform() const
+{
+ if (d)
+ return d->appliedTransform;
+ else
+ return UsePluginDefault;
+}
+
QQuickTextureFactory *QQuickPixmap::textureFactory() const
{
if (d)
@@ -1338,13 +1365,18 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &size)
void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &requestSize, QQuickPixmap::Options options)
{
+ load(engine, url, requestSize, options, UsePluginDefault);
+}
+
+void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &requestSize, QQuickPixmap::Options options, AutoTransform requestAutoTransform)
+{
if (d) {
d->declarativePixmaps.remove(this);
d->release();
d = 0;
}
- QQuickPixmapKey key = { &url, &requestSize };
+ QQuickPixmapKey key = { &url, &requestSize, requestAutoTransform };
QQuickPixmapStore *store = pixmapStore();
QHash<QQuickPixmapKey, QQuickPixmapData *>::Iterator iter = store->m_cache.end();
@@ -1370,7 +1402,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
if (!(options & QQuickPixmap::Asynchronous)) {
bool ok = false;
PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(url));
- d = createPixmapDataSync(this, engine, url, requestSize, &ok);
+ d = createPixmapDataSync(this, engine, url, requestSize, requestAutoTransform, &ok);
if (ok) {
PIXMAP_PROFILE(pixmapLoadingFinished(url, QSize(width(), height())));
if (options & QQuickPixmap::Cache)
@@ -1386,7 +1418,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
if (!engine)
return;
- d = new QQuickPixmapData(this, url, requestSize);
+ d = new QQuickPixmapData(this, url, requestSize, requestAutoTransform, requestAutoTransform);
if (options & QQuickPixmap::Cache)
d->addToCache();
@@ -1422,7 +1454,7 @@ void QQuickPixmap::clear(QObject *obj)
bool QQuickPixmap::isCached(const QUrl &url, const QSize &requestSize)
{
- QQuickPixmapKey key = { &url, &requestSize };
+ QQuickPixmapKey key = { &url, &requestSize, UsePluginDefault };
QQuickPixmapStore *store = pixmapStore();
return store->m_cache.contains(key);