diff options
Diffstat (limited to 'src/gui/painting/qmemrotate.cpp')
-rw-r--r-- | src/gui/painting/qmemrotate.cpp | 275 |
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 |