summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qmemrotate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/painting/qmemrotate.cpp')
-rw-r--r--src/gui/painting/qmemrotate.cpp275
1 files changed, 55 insertions, 220 deletions
diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp
index 3fbae76de5..25aa6a3122 100644
--- a/src/gui/painting/qmemrotate.cpp
+++ b/src/gui/painting/qmemrotate.cpp
@@ -41,164 +41,10 @@
QT_BEGIN_NAMESPACE
-#if QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
static const int tileSize = 32;
-#endif
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
-#if QT_ROTATION_ALGORITHM == QT_ROTATION_PACKED || QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
-#error Big endian version not implemented for the transformed driver!
-#endif
-#endif
-
-template <class T>
-Q_STATIC_TEMPLATE_FUNCTION
-inline void qt_memrotate90_cachedRead(const T *src, int w, int h, int sstride, T *dest,
- int dstride)
-{
- const char *s = reinterpret_cast<const char*>(src);
- char *d = reinterpret_cast<char*>(dest);
- for (int y = 0; y < h; ++y) {
- for (int x = w - 1; x >= 0; --x) {
- T *destline = reinterpret_cast<T *>(d + (w - x - 1) * dstride);
- destline[y] = src[x];
- }
- s += sstride;
- src = reinterpret_cast<const T*>(s);
- }
-}
template <class T>
Q_STATIC_TEMPLATE_FUNCTION
-inline void qt_memrotate270_cachedRead(const T *src, int w, int h, int sstride, T *dest,
- int dstride)
-{
- const char *s = reinterpret_cast<const char*>(src);
- char *d = reinterpret_cast<char*>(dest);
- s += (h - 1) * sstride;
- for (int y = h - 1; y >= 0; --y) {
- src = reinterpret_cast<const T*>(s);
- for (int x = 0; x < w; ++x) {
- T *destline = reinterpret_cast<T *>(d + x * dstride);
- destline[h - y - 1] = src[x];
- }
- s -= sstride;
- }
-}
-
-#if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
-
-template <class T>
-Q_STATIC_TEMPLATE_FUNCTION
-inline void qt_memrotate90_cachedWrite(const T *src, int w, int h, int sstride, T *dest,
- int dstride)
-{
- for (int x = w - 1; x >= 0; --x) {
- T *d = dest + (w - x - 1) * dstride;
- for (int y = 0; y < h; ++y) {
- *d++ = src[y * sstride + x];
- }
- }
-
-}
-
-template <class T>
-Q_STATIC_TEMPLATE_FUNCTION
-inline void qt_memrotate270_cachedWrite(const T *src, int w, int h, int sstride, T *dest,
- int dstride)
-{
- for (int x = 0; x < w; ++x) {
- T *d = dest + x * dstride;
- for (int y = h - 1; y >= 0; --y) {
- *d++ = src[y * sstride + x];
- }
- }
-}
-
-#endif // QT_ROTATION_CACHEDWRITE
-
-#if QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING
-
-// TODO: packing algorithms should probably be modified on 64-bit architectures
-
-template <class T>
-Q_STATIC_TEMPLATE_FUNCTION
-inline void qt_memrotate90_packing(const T *src, int w, int h, int sstride, T *dest, int dstride)
-{
- sstride /= sizeof(T);
- dstride /= sizeof(T);
-
- const int pack = sizeof(quint32) / sizeof(T);
- const int unaligned = int((long(dest) & (sizeof(quint32)-1))) / sizeof(T);
-
- for (int x = w - 1; x >= 0; --x) {
- int y = 0;
-
- for (int i = 0; i < unaligned; ++i) {
- dest[(w - x - 1) * dstride + y] = src[y * sstride + x];
- ++y;
- }
-
- quint32 *d = reinterpret_cast<quint32*>(dest + (w - x - 1) * dstride
- + unaligned);
- const int rest = (h - unaligned) % pack;
- while (y < h - rest) {
- quint32 c = src[y * sstride + x];
- for (int i = 1; i < pack; ++i) {
- c |= src[(y + i) * sstride + x] << (sizeof(int) * 8 / pack * i);
- }
- *d++ = c;
- y += pack;
- }
-
- while (y < h) {
- dest[(w - x - 1) * dstride + y] = src[y * sstride + x];
- ++y;
- }
- }
-}
-
-template <class T>
-Q_STATIC_TEMPLATE_FUNCTION
-inline void qt_memrotate270_packing(const T *src, int w, int h, int sstride, T *dest, int dstride)
-{
- sstride /= sizeof(T);
- dstride /= sizeof(T);
-
- const int pack = sizeof(quint32) / sizeof(T);
- const int unaligned = int((long(dest) & (sizeof(quint32)-1))) / sizeof(T);
-
- for (int x = 0; x < w; ++x) {
- int y = h - 1;
-
- for (int i = 0; i < unaligned; ++i) {
- dest[x * dstride + h - y - 1] = src[y * sstride + x];
- --y;
- }
-
- quint32 *d = reinterpret_cast<quint32*>(dest + x * dstride
- + unaligned);
- const int rest = (h - unaligned) % pack;
- while (y > rest) {
- quint32 c = src[y * sstride + x];
- for (int i = 1; i < pack; ++i) {
- c |= src[(y - i) * sstride + x] << (sizeof(int) * 8 / pack * i);
- }
- *d++ = c;
- y -= pack;
- }
- while (y >= 0) {
- dest[x * dstride + h - y - 1] = src[y * sstride + x];
- --y;
- }
- }
-}
-
-#endif // QT_ROTATION_PACKING
-
-#if QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
-template <class T>
-Q_STATIC_TEMPLATE_FUNCTION
inline void qt_memrotate90_tiled(const T *src, int w, int h, int sstride, T *dest, int dstride)
{
sstride /= sizeof(T);
@@ -235,7 +81,7 @@ inline void qt_memrotate90_tiled(const T *src, int w, int h, int sstride, T *des
for (int y = starty; y < stopy; y += pack) {
quint32 c = src[y * sstride + x];
for (int i = 1; i < pack; ++i) {
- const int shift = (sizeof(int) * 8 / pack * i);
+ const int shift = (sizeof(T) * 8 * i);
const T color = src[(y + i) * sstride + x];
c |= color << shift;
}
@@ -293,7 +139,7 @@ inline void qt_memrotate270_tiled(const T *src, int w, int h, int sstride, T *de
const int pack = sizeof(quint32) / sizeof(T);
const int unaligned =
- qMin(uint((long(dest) & (sizeof(quint32)-1)) / sizeof(T)), uint(h));
+ qMin(uint((quintptr(dest) & (sizeof(quint32)-1)) / sizeof(T)), uint(h));
const int restX = w % tileSize;
const int restY = (h - unaligned) % tileSize;
const int unoptimizedY = restY % pack;
@@ -320,10 +166,10 @@ inline void qt_memrotate270_tiled(const T *src, int w, int h, int sstride, T *de
for (int x = startx; x < stopx; ++x) {
quint32 *d = reinterpret_cast<quint32*>(dest + x * dstride
+ h - 1 - starty);
- for (int y = starty; y > stopy; y -= pack) {
+ for (int y = starty; y >= stopy; y -= pack) {
quint32 c = src[y * sstride + x];
for (int i = 1; i < pack; ++i) {
- const int shift = (sizeof(int) * 8 / pack * i);
+ const int shift = (sizeof(T) * 8 * i);
const T color = src[(y - i) * sstride + x];
c |= color << shift;
}
@@ -371,22 +217,26 @@ inline void qt_memrotate270_tiled_unpacked(const T *src, int w, int h, int sstri
}
}
-#endif // QT_ROTATION_ALGORITHM
template <class T>
Q_STATIC_TEMPLATE_FUNCTION
inline void qt_memrotate90_template(const T *src, int srcWidth, int srcHeight, int srcStride,
T *dest, int dstStride)
{
-#if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD
- qt_memrotate90_cachedRead<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
-#elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
- qt_memrotate90_cachedWrite<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
-#elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING
- qt_memrotate90_packing<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
-#elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
- qt_memrotate90_tiled<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ // packed algorithm assumes little endian and that sizeof(quint32)/sizeof(T) is an integer
+ if (sizeof(quint32) % sizeof(T) == 0)
+ qt_memrotate90_tiled<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
+ else
#endif
+ qt_memrotate90_tiled_unpacked<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
+}
+
+template <>
+inline void qt_memrotate90_template<quint32>(const quint32 *src, int w, int h, int sstride, quint32 *dest, int dstride)
+{
+ // packed algorithm doesn't have any benefit for quint32
+ qt_memrotate90_tiled_unpacked(src, w, h, sstride, dest, dstride);
}
template <class T>
@@ -394,11 +244,11 @@ Q_STATIC_TEMPLATE_FUNCTION
inline void qt_memrotate180_template(const T *src, int w, int h, int sstride, T *dest, int dstride)
{
const char *s = (const char*)(src) + (h - 1) * sstride;
- for (int y = h - 1; y >= 0; --y) {
- T *d = reinterpret_cast<T*>((char *)(dest) + (h - y - 1) * dstride);
+ for (int dy = 0; dy < h; ++dy) {
+ T *d = reinterpret_cast<T*>((char *)(dest) + dy * dstride);
src = reinterpret_cast<const T*>(s);
- for (int x = w - 1; x >= 0; --x) {
- d[w - x - 1] = src[x];
+ for (int dx = 0; dx < w; ++dx) {
+ d[dx] = src[w - 1 - dx];
}
s -= sstride;
}
@@ -409,32 +259,20 @@ Q_STATIC_TEMPLATE_FUNCTION
inline void qt_memrotate270_template(const T *src, int srcWidth, int srcHeight, int srcStride,
T *dest, int dstStride)
{
-#if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD
- qt_memrotate270_cachedRead<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
-#elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
- qt_memrotate270_cachedWrite<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
-#elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING
- qt_memrotate270_packing<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
-#elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
- qt_memrotate270_tiled_unpacked<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ // packed algorithm assumes little endian and that sizeof(quint32)/sizeof(T) is an integer
+ if (sizeof(quint32) % sizeof(T) == 0)
+ qt_memrotate270_tiled<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
+ else
#endif
+ qt_memrotate270_tiled_unpacked<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
}
template <>
-inline void qt_memrotate90_template<quint24>(const quint24 *src, int srcWidth, int srcHeight,
- int srcStride, quint24 *dest, int dstStride)
+inline void qt_memrotate270_template<quint32>(const quint32 *src, int w, int h, int sstride, quint32 *dest, int dstride)
{
-#if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD
- qt_memrotate90_cachedRead<quint24>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
-#elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
- qt_memrotate90_cachedWrite<quint24>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
-#elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING
- // packed algorithm not implemented
- qt_memrotate90_cachedRead<quint24>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
-#elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
- // packed algorithm not implemented
- qt_memrotate90_tiled_unpacked<quint24>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
-#endif
+ // packed algorithm doesn't have any benefit for quint32
+ qt_memrotate270_tiled_unpacked(src, w, h, sstride, dest, dstride);
}
#define QT_IMPL_MEMROTATE(type) \
@@ -458,7 +296,7 @@ Q_GUI_EXPORT void qt_memrotate270(const type *src, int w, int h, int sstride, \
Q_GUI_EXPORT void qt_memrotate90(const type *src, int w, int h, int sstride, \
type *dest, int dstride) \
{ \
- qt_memrotate90_tiled_unpacked<type>(src, w, h, sstride, dest, dstride); \
+ qt_memrotate90_tiled_unpacked(src, w, h, sstride, dest, dstride); \
} \
Q_GUI_EXPORT void qt_memrotate180(const type *src, int w, int h, int sstride, \
type *dest, int dstride) \
@@ -468,7 +306,7 @@ Q_GUI_EXPORT void qt_memrotate180(const type *src, int w, int h, int sstride, \
Q_GUI_EXPORT void qt_memrotate270(const type *src, int w, int h, int sstride, \
type *dest, int dstride) \
{ \
- qt_memrotate270_tiled_unpacked<type>(src, w, h, sstride, dest, dstride); \
+ qt_memrotate270_tiled_unpacked(src, w, h, sstride, dest, dstride); \
}
@@ -509,6 +347,21 @@ void qt_memrotate270_16(const uchar *srcPixels, int w, int h, int sbpl, uchar *d
qt_memrotate270((const ushort *)srcPixels, w, h, sbpl, (ushort *)destPixels, dbpl);
}
+void qt_memrotate90_24(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
+{
+ qt_memrotate90((const quint24 *)srcPixels, w, h, sbpl, (quint24 *)destPixels, dbpl);
+}
+
+void qt_memrotate180_24(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
+{
+ qt_memrotate180((const quint24 *)srcPixels, w, h, sbpl, (quint24 *)destPixels, dbpl);
+}
+
+void qt_memrotate270_24(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
+{
+ qt_memrotate270((const quint24 *)srcPixels, w, h, sbpl, (quint24 *)destPixels, dbpl);
+}
+
void qt_memrotate90_32(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
{
qt_memrotate90((const uint *)srcPixels, w, h, sbpl, (uint *)destPixels, dbpl);
@@ -524,34 +377,16 @@ void qt_memrotate270_32(const uchar *srcPixels, int w, int h, int sbpl, uchar *d
qt_memrotate270((const uint *)srcPixels, w, h, sbpl, (uint *)destPixels, dbpl);
}
-MemRotateFunc qMemRotateFunctions[QImage::NImageFormats][3] =
+MemRotateFunc qMemRotateFunctions[QPixelLayout::BPPCount][3] =
// 90, 180, 270
{
- { 0, 0, 0 }, // Format_Invalid,
- { 0, 0, 0 }, // Format_Mono,
- { 0, 0, 0 }, // Format_MonoLSB,
- { 0, 0, 0 }, // Format_Indexed8,
- { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_RGB32,
- { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_ARGB32,
- { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_ARGB32_Premultiplied,
- { qt_memrotate90_16, qt_memrotate180_16, qt_memrotate270_16 }, // Format_RGB16,
- { 0, 0, 0 }, // Format_ARGB8565_Premultiplied,
- { 0, 0, 0 }, // Format_RGB666,
- { 0, 0, 0 }, // Format_ARGB6666_Premultiplied,
- { 0, 0, 0 }, // Format_RGB555,
- { 0, 0, 0 }, // Format_ARGB8555_Premultiplied,
- { 0, 0, 0 }, // Format_RGB888,
- { 0, 0, 0 }, // Format_RGB444,
- { 0, 0, 0 }, // Format_ARGB4444_Premultiplied,
- { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_RGBX8888,
- { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_RGBA8888,
- { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_RGBA8888_Premultiplied,
- { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_BGB30,
- { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_A2BGR30_Premultiplied,
- { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_RGB30,
- { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_A2RGB30_Premultiplied,
- { qt_memrotate90_8, qt_memrotate180_8, qt_memrotate270_8 }, // Format_Alpha8,
- { qt_memrotate90_8, qt_memrotate180_8, qt_memrotate270_8 }, // Format_Grayscale8,
+ { 0, 0, 0 }, // BPPNone,
+ { 0, 0, 0 }, // BPP1MSB,
+ { 0, 0, 0 }, // BPP1LSB,
+ { qt_memrotate90_8, qt_memrotate180_8, qt_memrotate270_8 }, // BPP8,
+ { qt_memrotate90_16, qt_memrotate180_16, qt_memrotate270_16 }, // BPP16,
+ { qt_memrotate90_24, qt_memrotate180_24, qt_memrotate270_24 }, // BPP24
+ { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // BPP32
};
QT_END_NAMESPACE