1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
/* vi: ts=8 sts=4 sw=4
*
*
* This file is part of the KDE project, module kdeui.
* Copyright (C) 2000 Geert Jansen <jansen@kde.org>
*
* You can Freely distribute this program under the GNU Library General
* Public License. See the file "COPYING.LIB" for the exact licensing terms.
*/
#ifndef __KPixmapIO_h_Included__
#define __KPixmapIO_h_Included__
#include <kdelibs_export.h>
class QPixmap;
class QImage;
class QPoint;
class QRect;
struct KPixmapIOPrivate;
/**
* @short Fast QImage to/from QPixmap conversion.
* @author Geert Jansen <jansen@kde.org>
* @version $Id$
*
* KPixmapIO implements a fast path for QPixmap to/from QImage conversions.
* It uses the MIT-SHM shared memory extension for this. If this extension is
* not available, it will fall back to standard Qt methods.
*
* <b>Typical usage:</b>\n
*
* You can use KPixmapIO for load/saving pixmaps.
*
* \code
* KPixmapIO io;
* pixmap = io.convertToPixmap(image);
* image = io.convertToImage(pixmap);
* \endcode
*
* It also has functionality for partially updating/saving pixmaps, see
* putImage and getImage.
*
* <b>KPixmapIO vs. Qt speed comparison</b>\n
*
* Speed measurements were taken. These show that usage of KPixmapIO for
* images up to a certain threshold size, offers no speed advantage over
* the Qt routines. Below you can see a plot of these measurements.
*
* @image html kpixmapio-perf.png "Performance of KPixmapIO"
*
* The threshold size, amongst other causes, is determined by the shared
* memory allocation policy. If the policy is @p ShmDontKeep, the
* shared memory segment is discarded right after usage, and thus needs to
* be allocated before each transfer. This introduces a a setup penalty not
* present when the policy is @p ShmKeepAndGrow. In this case the
* shared memory segment is kept and resized when necessary, until the
* KPixmapIO object is destroyed.
*
* The default policy is @p ShmDontKeep. This policy makes sense when
* loading pixmaps once. The corresponding threshold is taken at 5.000
* pixels as suggested by experiments. Below this threshold, KPixmapIO
* will not use shared memory and fall back on the Qt routines.
*
* When the policy is @p ShmKeepAndGrow, the threshold is taken at
* 2.000 pixels. Using this policy, you might want to use preAllocShm
* to pre-allocate a certain amount of shared memory, in order to avoid
* resizes. This allocation policy makes sense in a multimedia type
* application where you are constantly updating the screen.
*
* Above a couple times the threshold size, KPixmapIO's and Qt's speed become
* linear in the number of pixels, KPixmapIO being at least 2, and mostly around
* 4 times faster than Qt, depending on the screen and image depth.
*
* Speed difference seems to be the most at 16 bpp, followed by 32 and 24
* bpp respectively. This can be explained by the relatively poor
* implementation of 16 bit RGB packing in Qt, while at 32 bpp we need to
* transfer more data, and thus gain more, than at 24 bpp.
*
* <b>Conclusion:</b>\n
*
* For large pixmaps, there's a definite speed improvement when using
* KPixmapIO. On the other hand, there's no speed improvement for small
* pixmaps. When you know you're only transferring small pixmaps, there's no
* point in using it.
*/
class KDEUI_EXPORT KPixmapIO
{
public:
KPixmapIO();
~KPixmapIO();
/**
* Convert an image to a pixmap.
* @param image The image to convert.
* @return The pixmap containing the image.
*/
QPixmap convertToPixmap(const QImage &image);
/**
* Convert a pixmap to an image.
* @param pixmap The pixmap to convert.
* @return The image.
*/
QImage convertToImage(const QPixmap &pixmap);
/**
* Bitblt an image onto a pixmap.
* @param dst The destination pixmap.
* @param dx Destination x offset.
* @param dy Destination y offset.
* @param src The image to load.
*/
void putImage(QPixmap *dst, int dx, int dy, const QImage *src);
/**
* This function is identical to the one above. It only differs in the
* arguments it accepts.
*/
void putImage(QPixmap *dst, const QPoint &offset, const QImage *src);
/**
* Transfer (a part of) a pixmap to an image.
* @param src The source pixmap.
* @param sx Source x offset.
* @param sy Source y offset.
* @param sw Source width.
* @param sh Source height.
* @return The image.
*/
QImage getImage(const QPixmap *src, int sx, int sy, int sw, int sh);
/**
* This function is identical to the one above. It only differs in the
* arguments it accepts.
*/
QImage getImage(const QPixmap *src, const QRect &rect);
/**
* Shared memory allocation policies.
*/
enum ShmPolicies {
ShmDontKeep,
ShmKeepAndGrow
};
/**
* Set the shared memory allocation policy. See the introduction for
* KPixmapIO for a discussion.
* @param policy The alloction policy.
*/
void setShmPolicy(int policy);
/**
* Pre-allocate shared memory. KPixmapIO will be able to transfer images
* up to this size without resizing.
* @param size The size of the image in @p pixels.
*/
void preAllocShm(int size);
private:
/*
* Supported XImage byte orders. The notation ARGB means bytes
* containing A:R:G:B succeed in memory.
*/
enum ByteOrders {
bo32_ARGB, bo32_BGRA, bo24_RGB, bo24_BGR,
bo16_RGB_565, bo16_BGR_565, bo16_RGB_555,
bo16_BGR_555, bo8
};
bool m_bShm;
bool initXImage(int w, int h);
void doneXImage();
bool createXImage(int w, int h);
void destroyXImage();
bool createShmSegment(int size);
void destroyShmSegment();
void convertToXImage(const QImage &);
QImage convertFromXImage();
private:
KPixmapIOPrivate* d;
};
#endif // __KPixmapIO_h_Included__
|