Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qmemrotate.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qmemrotate_p.h"
5#include "qpixellayout_p.h"
6
8
9static const int tileSize = 32;
10
11template<class T>
12static inline void qt_memrotate90_tiled(const T *src, int w, int h, int isstride, T *dest, int idstride)
13{
14 const qsizetype sstride = isstride / sizeof(T);
15 const qsizetype dstride = idstride / sizeof(T);
16
17 const int pack = sizeof(quint32) / sizeof(T);
18 const int unaligned =
19 qMin(uint((quintptr(dest) & (sizeof(quint32)-1)) / sizeof(T)), uint(h));
20 const int restX = w % tileSize;
21 const int restY = (h - unaligned) % tileSize;
22 const int unoptimizedY = restY % pack;
23 const int numTilesX = w / tileSize + (restX > 0);
24 const int numTilesY = (h - unaligned) / tileSize + (restY >= pack);
25
26 for (int tx = 0; tx < numTilesX; ++tx) {
27 const int startx = w - tx * tileSize - 1;
28 const int stopx = qMax(startx - tileSize, 0);
29
30 if (unaligned) {
31 for (int x = startx; x >= stopx; --x) {
32 T *d = dest + (w - x - 1) * dstride;
33 for (int y = 0; y < unaligned; ++y) {
34 *d++ = src[y * sstride + x];
35 }
36 }
37 }
38
39 for (int ty = 0; ty < numTilesY; ++ty) {
40 const int starty = ty * tileSize + unaligned;
41 const int stopy = qMin(starty + tileSize, h - unoptimizedY);
42
43 for (int x = startx; x >= stopx; --x) {
44 quint32 *d = reinterpret_cast<quint32*>(dest + (w - x - 1) * dstride + starty);
45 for (int y = starty; y < stopy; y += pack) {
46 quint32 c = src[y * sstride + x];
47 for (int i = 1; i < pack; ++i) {
48 const int shift = (sizeof(T) * 8 * i);
49 const T color = src[(y + i) * sstride + x];
50 c |= color << shift;
51 }
52 *d++ = c;
53 }
54 }
55 }
56
57 if (unoptimizedY) {
58 const int starty = h - unoptimizedY;
59 for (int x = startx; x >= stopx; --x) {
60 T *d = dest + (w - x - 1) * dstride + starty;
61 for (int y = starty; y < h; ++y) {
62 *d++ = src[y * sstride + x];
63 }
64 }
65 }
66 }
67}
68
69template<class T>
70static inline void qt_memrotate90_tiled_unpacked(const T *src, int w, int h, int isstride, T *dest, int idstride)
71{
72 const qsizetype sstride = isstride;
73 const qsizetype dstride = idstride;
74 const int numTilesX = (w + tileSize - 1) / tileSize;
75 const int numTilesY = (h + tileSize - 1) / tileSize;
76
77 for (int tx = 0; tx < numTilesX; ++tx) {
78 const int startx = w - tx * tileSize - 1;
79 const int stopx = qMax(startx - tileSize, 0);
80
81 for (int ty = 0; ty < numTilesY; ++ty) {
82 const int starty = ty * tileSize;
83 const int stopy = qMin(starty + tileSize, h);
84
85 for (int x = startx; x >= stopx; --x) {
86 T *d = (T *)((char*)dest + (w - x - 1) * dstride) + starty;
87 const char *s = (const char*)(src + x) + starty * sstride;
88 for (int y = starty; y < stopy; ++y) {
89 *d++ = *(const T *)(s);
90 s += sstride;
91 }
92 }
93 }
94 }
95}
96
97template<class T>
98static inline void qt_memrotate270_tiled(const T *src, int w, int h, int isstride, T *dest, int idstride)
99{
100 const qsizetype sstride = isstride / sizeof(T);
101 const qsizetype dstride = idstride / sizeof(T);
102
103 const int pack = sizeof(quint32) / sizeof(T);
104 const int unaligned =
105 qMin(uint((quintptr(dest) & (sizeof(quint32)-1)) / sizeof(T)), uint(h));
106 const int restX = w % tileSize;
107 const int restY = (h - unaligned) % tileSize;
108 const int unoptimizedY = restY % pack;
109 const int numTilesX = w / tileSize + (restX > 0);
110 const int numTilesY = (h - unaligned) / tileSize + (restY >= pack);
111
112 for (int tx = 0; tx < numTilesX; ++tx) {
113 const int startx = tx * tileSize;
114 const int stopx = qMin(startx + tileSize, w);
115
116 if (unaligned) {
117 for (int x = startx; x < stopx; ++x) {
118 T *d = dest + x * dstride;
119 for (int y = h - 1; y >= h - unaligned; --y) {
120 *d++ = src[y * sstride + x];
121 }
122 }
123 }
124
125 for (int ty = 0; ty < numTilesY; ++ty) {
126 const int starty = h - 1 - unaligned - ty * tileSize;
127 const int stopy = qMax(starty - tileSize, unoptimizedY);
128
129 for (int x = startx; x < stopx; ++x) {
130 quint32 *d = reinterpret_cast<quint32*>(dest + x * dstride
131 + h - 1 - starty);
132 for (int y = starty; y >= stopy; y -= pack) {
133 quint32 c = src[y * sstride + x];
134 for (int i = 1; i < pack; ++i) {
135 const int shift = (sizeof(T) * 8 * i);
136 const T color = src[(y - i) * sstride + x];
137 c |= color << shift;
138 }
139 *d++ = c;
140 }
141 }
142 }
143 if (unoptimizedY) {
144 const int starty = unoptimizedY - 1;
145 for (int x = startx; x < stopx; ++x) {
146 T *d = dest + x * dstride + h - 1 - starty;
147 for (int y = starty; y >= 0; --y) {
148 *d++ = src[y * sstride + x];
149 }
150 }
151 }
152 }
153}
154
155template<class T>
156static inline void qt_memrotate270_tiled_unpacked(const T *src, int w, int h, int isstride, T *dest, int idstride)
157{
158 const qsizetype sstride = isstride;
159 const qsizetype dstride = idstride;
160 const int numTilesX = (w + tileSize - 1) / tileSize;
161 const int numTilesY = (h + tileSize - 1) / tileSize;
162
163 for (int tx = 0; tx < numTilesX; ++tx) {
164 const int startx = tx * tileSize;
165 const int stopx = qMin(startx + tileSize, w);
166
167 for (int ty = 0; ty < numTilesY; ++ty) {
168 const int starty = h - 1 - ty * tileSize;
169 const int stopy = qMax(starty - tileSize, 0);
170
171 for (int x = startx; x < stopx; ++x) {
172 T *d = (T*)((char*)dest + x * dstride) + h - 1 - starty;
173 const char *s = (const char*)(src + x) + starty * sstride;
174 for (int y = starty; y >= stopy; --y) {
175 *d++ = *(const T*)s;
176 s -= sstride;
177 }
178 }
179 }
180 }
181}
182
183
184template <class T>
185static
186inline void qt_memrotate90_template(const T *src, int srcWidth, int srcHeight, int srcStride,
187 T *dest, int dstStride)
188{
189#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
190 // packed algorithm assumes little endian and that sizeof(quint32)/sizeof(T) is an integer
191 static_assert(sizeof(quint32) % sizeof(T) == 0);
192 qt_memrotate90_tiled<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
193#else
194 qt_memrotate90_tiled_unpacked<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
195#endif
196}
197
198template<class T>
199static inline void qt_memrotate180_template(const T *src, int w, int h, int isstride, T *dest, int idstride)
200{
201 const qsizetype sstride = isstride;
202 const qsizetype dstride = idstride;
203
204 const char *s = (const char*)(src) + (h - 1) * sstride;
205 for (int dy = 0; dy < h; ++dy) {
206 T *d = reinterpret_cast<T*>((char *)(dest) + dy * dstride);
207 src = reinterpret_cast<const T*>(s);
208 for (int dx = 0; dx < w; ++dx) {
209 d[dx] = src[w - 1 - dx];
210 }
211 s -= sstride;
212 }
213}
214
215template <class T>
216static
217inline void qt_memrotate270_template(const T *src, int srcWidth, int srcHeight, int srcStride,
218 T *dest, int dstStride)
219{
220#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
221 // packed algorithm assumes little endian and that sizeof(quint32)/sizeof(T) is an integer
222 static_assert(sizeof(quint32) % sizeof(T) == 0);
223 qt_memrotate270_tiled<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
224#else
225 qt_memrotate270_tiled_unpacked<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
226#endif
227}
228
229#define QT_IMPL_MEMROTATE(type) \
230Q_GUI_EXPORT void qt_memrotate90(const type *src, int w, int h, int sstride, \
231 type *dest, int dstride) \
232{ \
233 qt_memrotate90_template(src, w, h, sstride, dest, dstride); \
234} \
235Q_GUI_EXPORT void qt_memrotate180(const type *src, int w, int h, int sstride, \
236 type *dest, int dstride) \
237{ \
238 qt_memrotate180_template(src, w, h, sstride, dest, dstride); \
239} \
240Q_GUI_EXPORT void qt_memrotate270(const type *src, int w, int h, int sstride, \
241 type *dest, int dstride) \
242{ \
243 qt_memrotate270_template(src, w, h, sstride, dest, dstride); \
244}
245
246#define QT_IMPL_SIMPLE_MEMROTATE(type) \
247Q_GUI_EXPORT void qt_memrotate90(const type *src, int w, int h, int sstride, \
248 type *dest, int dstride) \
249{ \
250 qt_memrotate90_tiled_unpacked(src, w, h, sstride, dest, dstride); \
251} \
252Q_GUI_EXPORT void qt_memrotate180(const type *src, int w, int h, int sstride, \
253 type *dest, int dstride) \
254{ \
255 qt_memrotate180_template(src, w, h, sstride, dest, dstride); \
256} \
257Q_GUI_EXPORT void qt_memrotate270(const type *src, int w, int h, int sstride, \
258 type *dest, int dstride) \
259{ \
260 qt_memrotate270_tiled_unpacked(src, w, h, sstride, dest, dstride); \
261}
262
269
270void qt_memrotate90_8(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
271{
272 qt_memrotate90(srcPixels, w, h, sbpl, destPixels, dbpl);
273}
274
275void qt_memrotate180_8(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
276{
277 qt_memrotate180(srcPixels, w, h, sbpl, destPixels, dbpl);
278}
279
280void qt_memrotate270_8(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
281{
282 qt_memrotate270(srcPixels, w, h, sbpl, destPixels, dbpl);
283}
284
285void qt_memrotate90_16(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
286{
287 qt_memrotate90((const ushort *)srcPixels, w, h, sbpl, (ushort *)destPixels, dbpl);
288}
289
290void qt_memrotate180_16(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
291{
292 qt_memrotate180((const ushort *)srcPixels, w, h, sbpl, (ushort *)destPixels, dbpl);
293}
294
295void qt_memrotate270_16(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
296{
297 qt_memrotate270((const ushort *)srcPixels, w, h, sbpl, (ushort *)destPixels, dbpl);
298}
299
300void qt_memrotate90_24(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
301{
302 qt_memrotate90((const quint24 *)srcPixels, w, h, sbpl, (quint24 *)destPixels, dbpl);
303}
304
305void qt_memrotate180_24(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
306{
307 qt_memrotate180((const quint24 *)srcPixels, w, h, sbpl, (quint24 *)destPixels, dbpl);
308}
309
310void qt_memrotate270_24(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
311{
312 qt_memrotate270((const quint24 *)srcPixels, w, h, sbpl, (quint24 *)destPixels, dbpl);
313}
314
315void qt_memrotate90_32(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
316{
317 qt_memrotate90((const uint *)srcPixels, w, h, sbpl, (uint *)destPixels, dbpl);
318}
319
320void qt_memrotate180_32(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
321{
322 qt_memrotate180((const uint *)srcPixels, w, h, sbpl, (uint *)destPixels, dbpl);
323}
324
325void qt_memrotate270_32(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
326{
327 qt_memrotate270((const uint *)srcPixels, w, h, sbpl, (uint *)destPixels, dbpl);
328}
329
330
331void qt_memrotate90_64(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
332{
333 qt_memrotate90((const quint64 *)srcPixels, w, h, sbpl, (quint64 *)destPixels, dbpl);
334}
335
336void qt_memrotate180_64(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
337{
338 qt_memrotate180((const quint64 *)srcPixels, w, h, sbpl, (quint64 *)destPixels, dbpl);
339}
340
341void qt_memrotate270_64(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
342{
343 qt_memrotate270((const quint64 *)srcPixels, w, h, sbpl, (quint64 *)destPixels, dbpl);
344}
345
346void qt_memrotate90_128(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
347{
348 qt_memrotate90((const QRgbaFloat32 *)srcPixels, w, h, sbpl, (QRgbaFloat32 *)destPixels, dbpl);
349}
350
351void qt_memrotate180_128(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
352{
353 qt_memrotate180((const QRgbaFloat32 *)srcPixels, w, h, sbpl, (QRgbaFloat32 *)destPixels, dbpl);
354}
355
356void qt_memrotate270_128(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
357{
358 qt_memrotate270((const QRgbaFloat32 *)srcPixels, w, h, sbpl, (QRgbaFloat32 *)destPixels, dbpl);
359}
360
362// 90, 180, 270
363{
364 { nullptr, nullptr, nullptr }, // BPPNone,
365 { nullptr, nullptr, nullptr }, // BPP1MSB,
366 { nullptr, nullptr, nullptr }, // BPP1LSB,
374};
375
Combined button and popup list for selecting options.
static QT_WARNING_DISABLE_FLOAT_COMPARE ShiftResult shift(const QBezier *orig, QBezier *shifted, qreal offset, qreal threshold)
Definition qbezier.cpp:207
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
void qt_memrotate90_16(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
void qt_memrotate90_128(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
void qt_memrotate270_24(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
void qt_memrotate270_64(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
static void qt_memrotate270_template(const T *src, int srcWidth, int srcHeight, int srcStride, T *dest, int dstStride)
void qt_memrotate270_32(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
static void qt_memrotate270_tiled(const T *src, int w, int h, int isstride, T *dest, int idstride)
void qt_memrotate180_32(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
void qt_memrotate270_16(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
#define QT_IMPL_SIMPLE_MEMROTATE(type)
static void qt_memrotate90_template(const T *src, int srcWidth, int srcHeight, int srcStride, T *dest, int dstStride)
void qt_memrotate90_24(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
void qt_memrotate180_16(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
void qt_memrotate270_128(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
void qt_memrotate180_24(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
void qt_memrotate270_8(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
void qt_memrotate90_32(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
static void qt_memrotate270_tiled_unpacked(const T *src, int w, int h, int isstride, T *dest, int idstride)
MemRotateFunc qMemRotateFunctions[QPixelLayout::BPPCount][3]
void qt_memrotate90_8(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
void qt_memrotate180_8(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
static void qt_memrotate180_template(const T *src, int w, int h, int isstride, T *dest, int idstride)
void qt_memrotate180_128(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
void qt_memrotate90_64(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
static QT_BEGIN_NAMESPACE const int tileSize
Definition qmemrotate.cpp:9
static void qt_memrotate90_tiled_unpacked(const T *src, int w, int h, int isstride, T *dest, int idstride)
void qt_memrotate180_64(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
#define QT_IMPL_MEMROTATE(type)
static void qt_memrotate90_tiled(const T *src, int w, int h, int isstride, T *dest, int idstride)
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLenum GLint GLint GLint GLint GLuint GLenum GLint GLint GLint GLint GLsizei GLsizei srcHeight
GLint GLint GLint GLint GLint x
[0]
GLfloat GLfloat GLfloat w
[0]
GLenum GLint GLint GLint GLint GLuint GLenum GLint GLint GLint GLint GLsizei srcWidth
GLenum src
GLuint color
[2]
GLint y
GLfloat GLfloat GLfloat GLfloat h
GLdouble s
[6]
Definition qopenglext.h:235
const GLubyte * c
GLbyte ty
void(* MemRotateFunc)(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
unsigned int quint32
Definition qtypes.h:50
unsigned char uchar
Definition qtypes.h:32
unsigned short quint16
Definition qtypes.h:48
size_t quintptr
Definition qtypes.h:167
unsigned long long quint64
Definition qtypes.h:61
ptrdiff_t qsizetype
Definition qtypes.h:165
unsigned int uint
Definition qtypes.h:34
unsigned short ushort
Definition qtypes.h:33
unsigned char quint8
Definition qtypes.h:46