Skip to content

Commit d2fa35a

Browse files
Merge branch 'experimental/abstract_scaling' into develop
2 parents 405c8d7 + 42b4376 commit d2fa35a

23 files changed

+2077
-563
lines changed

src/ImageViewer/ImageViewer.pro

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,12 @@ SOURCES += \
7171
src/Decoders/Impl/Internal/Animation/AnimationWidget.cpp \
7272
src/Decoders/Impl/Internal/Animation/FramesCompositor.cpp \
7373
src/Decoders/Impl/Internal/Animation/AbstractAnimationProvider.cpp \
74-
src/Decoders/Impl/Internal/GraphicsItems/ImageResamplerWorker.cpp \
74+
src/Decoders/Impl/Internal/GraphicsItems/AbstractScalingManager.cpp \
75+
src/Decoders/Impl/Internal/GraphicsItems/AbstractScalingWorker.cpp \
76+
src/Decoders/Impl/Internal/GraphicsItems/AbstractScalingWorkerHandler.cpp \
77+
src/Decoders/Impl/Internal/GraphicsItems/AutoUpdatedScalingWorkerHandler.cpp \
78+
src/Decoders/Impl/Internal/GraphicsItems/GraphicsItemUtils.cpp \
79+
src/Decoders/Impl/Internal/GraphicsItems/RasterizedImageGraphicsItem.cpp \
7580
src/Decoders/Impl/Internal/GraphicsItems/ResampledImageGraphicsItem.cpp \
7681
src/Decoders/Impl/Internal/Utils/ExifUtils.cpp \
7782
src/Decoders/Impl/Internal/Utils/CmsUtils.cpp \
@@ -95,7 +100,12 @@ HEADERS += \
95100
src/Decoders/Impl/Internal/Animation/FramesCompositor.h \
96101
src/Decoders/Impl/Internal/Animation/IAnimationProvider.h \
97102
src/Decoders/Impl/Internal/Animation/AbstractAnimationProvider.h \
98-
src/Decoders/Impl/Internal/GraphicsItems/ImageResamplerWorker.h \
103+
src/Decoders/Impl/Internal/GraphicsItems/AbstractScalingManager.h \
104+
src/Decoders/Impl/Internal/GraphicsItems/AbstractScalingWorker.h \
105+
src/Decoders/Impl/Internal/GraphicsItems/AbstractScalingWorkerHandler.h \
106+
src/Decoders/Impl/Internal/GraphicsItems/AutoUpdatedScalingWorkerHandler.h \
107+
src/Decoders/Impl/Internal/GraphicsItems/GraphicsItemUtils.h \
108+
src/Decoders/Impl/Internal/GraphicsItems/RasterizedImageGraphicsItem.h \
99109
src/Decoders/Impl/Internal/GraphicsItems/ResampledImageGraphicsItem.h \
100110
src/Decoders/Impl/Internal/Utils/ExifUtils.h \
101111
src/Decoders/Impl/Internal/Utils/CmsUtils.h \

src/ImageViewer/src/Decoders/Impl/DecoderLibWmf.cpp

Lines changed: 23 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,13 @@
2727

2828
#include <QFileInfo>
2929
#include <QImage>
30-
#include <QPixmap>
3130
#include <QFile>
3231
#include <QByteArray>
33-
#include <QGraphicsItem>
3432
#include <QPainter>
3533
#include <QDebug>
3634

3735
#include "../IDecoder.h"
36+
#include "Internal/GraphicsItems/RasterizedImageGraphicsItem.h"
3837
#include "Internal/DecoderAutoRegistrator.h"
3938
#include "Internal/Utils/ZLibUtils.h"
4039

@@ -75,18 +74,17 @@ const char *wmfErrorToString(wmf_error_t error)
7574

7675
// ====================================================================================================
7776

78-
class WmfGraphicsItem : public QGraphicsItem
77+
class WmfPixmapProvider : public RasterizedImageGraphicsItem::IRasterizedImageProvider
7978
{
8079
public:
81-
WmfGraphicsItem(const QString &filePath)
80+
WmfPixmapProvider(const QString &filePath)
8281
: m_isValid(false)
8382
, m_API(NULL)
8483
, m_ddata(NULL)
8584
, m_width(0)
8685
, m_height(0)
8786
, m_minScaleFactor(1)
8887
, m_maxScaleFactor(1)
89-
, m_cachedScaleFactor(0)
9088
{
9189
memset(&m_bbox, 0, sizeof(wmfD_Rect));
9290

@@ -164,7 +162,7 @@ class WmfGraphicsItem : public QGraphicsItem
164162
m_maxScaleFactor = std::min(MAX_IMAGE_DIMENSION / m_width, MAX_IMAGE_DIMENSION / m_height);
165163
}
166164

167-
~WmfGraphicsItem()
165+
~WmfPixmapProvider()
168166
{
169167
if(!isValid())
170168
return;
@@ -182,37 +180,7 @@ class WmfGraphicsItem : public QGraphicsItem
182180
return QRectF(0, 0, m_width, m_height);
183181
}
184182

185-
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = NULL)
186-
{
187-
Q_UNUSED(option);
188-
Q_UNUSED(widget);
189-
if(!isValid())
190-
return;
191-
192-
const QRectF identityRect = QRectF(0, 0, 1, 1);
193-
const QRectF deviceTransformedRect = painter->deviceTransform().mapRect(identityRect);
194-
const qreal deviceScaleFactor = std::max(deviceTransformedRect.width(), deviceTransformedRect.height());
195-
const qreal actualScaleFactor = std::min(std::max(m_minScaleFactor, deviceScaleFactor), m_maxScaleFactor);
196-
if(std::abs(actualScaleFactor - m_cachedScaleFactor) / std::max(actualScaleFactor, m_cachedScaleFactor) > 1e-2)
197-
{
198-
const bool previousPixmapIsValid = !m_cachedPixmap.isNull();
199-
m_cachedPixmap = QPixmap();
200-
m_cachedPixmap = getPixmap(actualScaleFactor);
201-
if(m_cachedPixmap.isNull() && previousPixmapIsValid)
202-
{
203-
m_maxScaleFactor = m_cachedScaleFactor;
204-
m_cachedPixmap = getPixmap(m_cachedScaleFactor);
205-
}
206-
else
207-
{
208-
m_cachedScaleFactor = actualScaleFactor;
209-
}
210-
}
211-
painter->drawPixmap(boundingRect(), m_cachedPixmap, QRectF(0, 0, m_width * m_cachedScaleFactor, m_height * m_cachedScaleFactor));
212-
}
213-
214-
protected:
215-
QPixmap getPixmap(const qreal scaleFactor)
183+
QImage image(const qreal scaleFactor)
216184
{
217185
m_ddata->type = wmf_gd_image;
218186
m_ddata->bbox.TL.x = m_bbox.TL.x;
@@ -226,14 +194,14 @@ class WmfGraphicsItem : public QGraphicsItem
226194
if(error != wmf_E_None)
227195
{
228196
qWarning() << "Couldn't decode WMF file into pixbuf:" << wmfErrorToString(error);
229-
return QPixmap();
197+
return QImage();
230198
}
231199

232200
int *gdPixels = NULL;
233201
if(m_ddata->gd_image == NULL || (gdPixels = wmf_gd_image_pixels(m_ddata->gd_image)) == NULL)
234202
{
235203
qWarning() << "Couldn't decode WMF file - no output (huh?)" << wmfErrorToString(error);
236-
return QPixmap();
204+
return QImage();
237205
}
238206

239207
QImage image(static_cast<int>(m_ddata->width), static_cast<int>(m_ddata->height), QImage::Format_ARGB32);
@@ -254,11 +222,21 @@ class WmfGraphicsItem : public QGraphicsItem
254222
*(imagePtr++) = qRgba(r, g, b, a);
255223
}
256224
}
257-
return QPixmap::fromImage(image);
225+
return image;
226+
}
227+
228+
qreal minScaleFactor() const
229+
{
230+
return m_minScaleFactor;
231+
}
232+
233+
qreal maxScaleFactor() const
234+
{
235+
return m_maxScaleFactor;
258236
}
259237

260238
private:
261-
Q_DISABLE_COPY(WmfGraphicsItem)
239+
Q_DISABLE_COPY(WmfPixmapProvider)
262240

263241
bool m_isValid;
264242
QByteArray m_inBuffer;
@@ -269,9 +247,6 @@ class WmfGraphicsItem : public QGraphicsItem
269247
unsigned int m_height;
270248
qreal m_minScaleFactor;
271249
qreal m_maxScaleFactor;
272-
273-
QPixmap m_cachedPixmap;
274-
qreal m_cachedScaleFactor;
275250
};
276251

277252
// ====================================================================================================
@@ -302,13 +277,11 @@ class DecoderLibWmf : public IDecoder
302277
if(!fileInfo.exists() || !fileInfo.isReadable())
303278
return NULL;
304279

305-
WmfGraphicsItem *item = new WmfGraphicsItem(filePath);
306-
if(!item->isValid())
307-
{
308-
delete item;
280+
QSharedPointer<WmfPixmapProvider> provider(new WmfPixmapProvider(filePath));
281+
if(!provider->isValid())
309282
return NULL;
310-
}
311-
return item;
283+
284+
return new RasterizedImageGraphicsItem(provider);
312285
}
313286
};
314287

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
Copyright (C) 2017 Peter S. Zhigalov <[email protected]>
3+
4+
This file is part of the `ImageViewer' program.
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
#include "AbstractScalingManager.h"
21+
22+
#include <QObject>
23+
#include <QThread>
24+
25+
#include "AbstractScalingWorker.h"
26+
#include "AbstractScalingWorkerHandler.h"
27+
28+
AbstractScalingManager::AbstractScalingManager(AbstractScalingWorker *worker, AbstractScalingWorkerHandler *handler, QThread *thread)
29+
: m_scalingWorker(worker)
30+
, m_scalingThread(thread)
31+
, m_scalingWorkerHandler(handler)
32+
{
33+
m_scalingWorker->moveToThread(m_scalingThread);
34+
QObject::connect(m_scalingThread, SIGNAL(started()), m_scalingWorker, SLOT(process()));
35+
}
36+
37+
AbstractScalingManager::~AbstractScalingManager()
38+
{
39+
abortTask();
40+
m_scalingWorkerHandler->setDestroyOnFinished();
41+
}
42+
43+
void AbstractScalingManager::startTask(const qreal scaleFactor)
44+
{
45+
if(m_scalingWorkerHandler->isRunning())
46+
return;
47+
48+
abortTask();
49+
m_scalingWorker->setScaleFactor(scaleFactor);
50+
m_scalingThread->start();
51+
}
52+
53+
void AbstractScalingManager::abortTask()
54+
{
55+
m_scalingWorker->abort();
56+
}
57+
58+
void AbstractScalingManager::beginScaledImageProcessing()
59+
{
60+
m_scalingWorker->lockScaledImage();
61+
}
62+
63+
void AbstractScalingManager::endScaledImageProcessing()
64+
{
65+
m_scalingWorker->unlockScaledImage();
66+
}
67+
68+
bool AbstractScalingManager::hasScaledData() const
69+
{
70+
return m_scalingWorker->hasScaledData();
71+
}
72+
73+
QImage AbstractScalingManager::getScaledImage() const
74+
{
75+
return m_scalingWorker->getScaledImage();
76+
}
77+
78+
qreal AbstractScalingManager::getScaledScaleFactor() const
79+
{
80+
return m_scalingWorker->getScaledScaleFactor();
81+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
Copyright (C) 2017 Peter S. Zhigalov <[email protected]>
3+
4+
This file is part of the `ImageViewer' program.
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
#if !defined(ABSTRACT_SCALING_MANAGER_H_INCLUDED)
21+
#define ABSTRACT_SCALING_MANAGER_H_INCLUDED
22+
23+
#include <QImage>
24+
25+
#include "Utils/ScopedPointer.h"
26+
27+
class QThread;
28+
class AbstractScalingWorker;
29+
class AbstractScalingWorkerHandler;
30+
31+
class AbstractScalingManager
32+
{
33+
public:
34+
AbstractScalingManager(AbstractScalingWorker *worker, AbstractScalingWorkerHandler *handler, QThread *thread);
35+
~AbstractScalingManager();
36+
37+
void startTask(const qreal scaleFactor);
38+
void abortTask();
39+
40+
void beginScaledImageProcessing();
41+
void endScaledImageProcessing();
42+
43+
bool hasScaledData() const;
44+
QImage getScaledImage() const;
45+
qreal getScaledScaleFactor() const;
46+
47+
protected:
48+
AbstractScalingWorker *m_scalingWorker;
49+
QThread *m_scalingThread;
50+
AbstractScalingWorkerHandler *m_scalingWorkerHandler;
51+
52+
private:
53+
Q_DISABLE_COPY(AbstractScalingManager)
54+
};
55+
56+
#endif // ABSTRACT_SCALING_MANAGER_H_INCLUDED

0 commit comments

Comments
 (0)