2
* Copyright (C) 2011-2014 Canonical Ltd
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License version 3 as
6
* published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
* Lucas Beeler <lucas@yorba.org>
18
* Jim Nelson <jim@yorba.org>
19
* Ugo Riboni <ugo.riboni@canonical.com>
22
#ifndef PHOTO_IMAGE_PROVIDER_H_
23
#define PHOTO_IMAGE_PROVIDER_H_
26
#include "orientation.h"
34
#include <QQuickImageProvider>
40
* We use a custom image provider for the following reasons:
42
* 1. QML's image loader does not respect EXIF orientation. This provider will
43
* rotate and mirror the image as necessary.
45
* 2. QML's image caching appears to be directly related to image size (scaling)
46
* which leads to thrashing when animating a thumbnail or loading images at
48
* The strategy here is to cache the largest requested size of the image
49
* and downscale it if smaller versions are requested. This minimizes
50
* expensive JPEG load-and-decodes.
52
* 3. Logging allows for monitoring of all image I/O, useful when debugging and
53
* optimizing, and signals can be emitted to monitor and test cache operation.
55
* 4. The QML cache does not check if a file has been modified on disk after it
56
* was cached, but our cache does. You should always set Image.cache to false
57
* when loading images from this provider in QML.
59
class PhotoImageProvider : public QObject, public QQuickImageProvider
64
static const char* PROVIDER_ID;
65
static const char* PROVIDER_ID_SCHEME;
68
virtual ~PhotoImageProvider();
70
virtual QImage requestImage(const QString& id, QSize* size,
71
const QSize& requestedSize);
73
void setLogging(bool enableLogging);
74
void setEmitCacheSignals(bool emitCacheSignals);
77
void cacheHit(QString id, QSize size);
78
void cacheMiss(QString id, QSize size, bool wasStale);
79
void cacheAdd(QString id, QSize size, QSize cachedSize);
87
// these fields should only be accessed when imageMutex_ is locked
90
Orientation orientation;
93
// the following should only be accessed when cacheMutex_ is locked; the
94
// counter controls removing a CachedImage entry from the cache table
98
CachedImage(const QString& id);
100
void storeImage(const QImage& newImage, const QSize& newFullSize,
101
Orientation newOrientation);
102
bool isFullSized() const;
103
bool isReady() const;
104
bool isCacheHit(const QSize& requestedSize) const;
107
QMap<QString, CachedImage*> m_cache;
108
QList<QString> m_cachingOrder;
111
bool m_logImageLoading;
112
bool m_emitCacheSignals;
114
static QSize orientSize(const QSize& size, Orientation orientation);
116
CachedImage* claimCachedImageEntry(const QString& id, QString& loggingStr);
118
QImage fetchCachedImage(CachedImage* cachedImage, const QSize& requestedSize,
119
uint* bytesLoaded, QString& loggingStr);
121
void releaseCachedImageEntry(CachedImage* cachedImage, uint bytesLoaded);
124
#endif // PHOTO_IMAGE_PROVIDER_H_