Cleanup memrotate functions

Throw out unused code and simply format table to only care about bpp
and use it consistently for all bpp.

Also makes QImage use the 180 degree memrotate, and fixes the tiled
packed qt_memrotate270 so it can be put to use.

Change-Id: If4ef1666fca960ce8e4ce32d85dc5f347b6986f4
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
This commit is contained in:
Allan Sandfeld Jensen 2016-09-29 14:28:02 +02:00 committed by Allan Sandfeld Jensen
parent 7a93d98f29
commit 7c401397a4
6 changed files with 90 additions and 358 deletions

View File

@ -4489,7 +4489,8 @@ QImage QImage::smoothScaled(int w, int h) const {
return src;
}
static QImage rotated90(const QImage &image) {
static QImage rotated90(const QImage &image)
{
QImage out(image.height(), image.width(), image.format());
out.setDotsPerMeterX(image.dotsPerMeterY());
out.setDotsPerMeterY(image.dotsPerMeterX());
@ -4497,49 +4498,10 @@ static QImage rotated90(const QImage &image) {
out.setColorTable(image.colorTable());
int w = image.width();
int h = image.height();
switch (image.format()) {
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
case QImage::Format_ARGB32_Premultiplied:
case QImage::Format_RGBX8888:
case QImage::Format_RGBA8888:
case QImage::Format_RGBA8888_Premultiplied:
case QImage::Format_BGR30:
case QImage::Format_A2BGR30_Premultiplied:
case QImage::Format_RGB30:
case QImage::Format_A2RGB30_Premultiplied:
qt_memrotate270(reinterpret_cast<const quint32*>(image.bits()),
w, h, image.bytesPerLine(),
reinterpret_cast<quint32*>(out.bits()),
out.bytesPerLine());
break;
case QImage::Format_RGB666:
case QImage::Format_ARGB6666_Premultiplied:
case QImage::Format_ARGB8565_Premultiplied:
case QImage::Format_ARGB8555_Premultiplied:
case QImage::Format_RGB888:
qt_memrotate270(reinterpret_cast<const quint24*>(image.bits()),
w, h, image.bytesPerLine(),
reinterpret_cast<quint24*>(out.bits()),
out.bytesPerLine());
break;
case QImage::Format_RGB555:
case QImage::Format_RGB16:
case QImage::Format_ARGB4444_Premultiplied:
qt_memrotate270(reinterpret_cast<const quint16*>(image.bits()),
w, h, image.bytesPerLine(),
reinterpret_cast<quint16*>(out.bits()),
out.bytesPerLine());
break;
case QImage::Format_Alpha8:
case QImage::Format_Grayscale8:
case QImage::Format_Indexed8:
qt_memrotate270(reinterpret_cast<const quint8*>(image.bits()),
w, h, image.bytesPerLine(),
reinterpret_cast<quint8*>(out.bits()),
out.bytesPerLine());
break;
default:
const MemRotateFunc memrotate = qMemRotateFunctions[qPixelLayouts[image.format()].bpp][2];
if (memrotate) {
memrotate(image.constBits(), w, h, image.bytesPerLine(), out.bits(), out.bytesPerLine());
} else {
for (int y=0; y<h; ++y) {
if (image.colorCount())
for (int x=0; x<w; ++x)
@ -4548,18 +4510,29 @@ static QImage rotated90(const QImage &image) {
for (int x=0; x<w; ++x)
out.setPixel(h-y-1, x, image.pixel(x, y));
}
break;
}
return out;
}
static QImage rotated180(const QImage &image)
{
const MemRotateFunc memrotate = qMemRotateFunctions[qPixelLayouts[image.format()].bpp][1];
if (!memrotate)
return image.mirrored(true, true);
static QImage rotated180(const QImage &image) {
return image.mirrored(true, true);
QImage out(image.width(), image.height(), image.format());
out.setDotsPerMeterX(image.dotsPerMeterY());
out.setDotsPerMeterY(image.dotsPerMeterX());
if (image.colorCount() > 0)
out.setColorTable(image.colorTable());
int w = image.width();
int h = image.height();
memrotate(image.constBits(), w, h, image.bytesPerLine(), out.bits(), out.bytesPerLine());
return out;
}
static QImage rotated270(const QImage &image) {
static QImage rotated270(const QImage &image)
{
QImage out(image.height(), image.width(), image.format());
out.setDotsPerMeterX(image.dotsPerMeterY());
out.setDotsPerMeterY(image.dotsPerMeterX());
@ -4567,49 +4540,10 @@ static QImage rotated270(const QImage &image) {
out.setColorTable(image.colorTable());
int w = image.width();
int h = image.height();
switch (image.format()) {
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
case QImage::Format_ARGB32_Premultiplied:
case QImage::Format_RGBX8888:
case QImage::Format_RGBA8888:
case QImage::Format_RGBA8888_Premultiplied:
case QImage::Format_BGR30:
case QImage::Format_A2BGR30_Premultiplied:
case QImage::Format_RGB30:
case QImage::Format_A2RGB30_Premultiplied:
qt_memrotate90(reinterpret_cast<const quint32*>(image.bits()),
w, h, image.bytesPerLine(),
reinterpret_cast<quint32*>(out.bits()),
out.bytesPerLine());
break;
case QImage::Format_RGB666:
case QImage::Format_ARGB6666_Premultiplied:
case QImage::Format_ARGB8565_Premultiplied:
case QImage::Format_ARGB8555_Premultiplied:
case QImage::Format_RGB888:
qt_memrotate90(reinterpret_cast<const quint24*>(image.bits()),
w, h, image.bytesPerLine(),
reinterpret_cast<quint24*>(out.bits()),
out.bytesPerLine());
break;
case QImage::Format_RGB555:
case QImage::Format_RGB16:
case QImage::Format_ARGB4444_Premultiplied:
qt_memrotate90(reinterpret_cast<const quint16*>(image.bits()),
w, h, image.bytesPerLine(),
reinterpret_cast<quint16*>(out.bits()),
out.bytesPerLine());
break;
case QImage::Format_Alpha8:
case QImage::Format_Grayscale8:
case QImage::Format_Indexed8:
qt_memrotate90(reinterpret_cast<const quint8*>(image.bits()),
w, h, image.bytesPerLine(),
reinterpret_cast<quint8*>(out.bits()),
out.bytesPerLine());
break;
default:
const MemRotateFunc memrotate = qMemRotateFunctions[qPixelLayouts[image.format()].bpp][0];
if (memrotate) {
memrotate(image.constBits(), w, h, image.bytesPerLine(), out.bits(), out.bytesPerLine());
} else {
for (int y=0; y<h; ++y) {
if (image.colorCount())
for (int x=0; x<w; ++x)
@ -4618,7 +4552,6 @@ static QImage rotated270(const QImage &image) {
for (int x=0; x<w; ++x)
out.setPixel(y, w-x-1, image.pixel(x, y));
}
break;
}
return out;
}

View File

@ -157,7 +157,6 @@ struct DrawHelper {
extern SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats];
extern SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats];
extern SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFormats];
extern MemRotateFunc qMemRotateFunctions[QImage::NImageFormats][3];
extern DrawHelper qDrawHelper[QImage::NImageFormats];
@ -1226,6 +1225,7 @@ extern QPixelLayout qPixelLayouts[QImage::NImageFormats];
extern const FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount];
extern StorePixelsFunc qStorePixels[QPixelLayout::BPPCount];
extern MemRotateFunc qMemRotateFunctions[QPixelLayout::BPPCount][3];
QT_END_NAMESPACE

View File

@ -41,162 +41,8 @@
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)
@ -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

View File

@ -56,19 +56,6 @@
QT_BEGIN_NAMESPACE
#define QT_ROTATION_CACHEDREAD 1
#define QT_ROTATION_CACHEDWRITE 2
#define QT_ROTATION_PACKING 3
#define QT_ROTATION_TILED 4
#ifndef QT_ROTATION_ALGORITHM
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
#define QT_ROTATION_ALGORITHM QT_ROTATION_TILED
#else
#define QT_ROTATION_ALGORITHM QT_ROTATION_CACHEDREAD
#endif
#endif
#define QT_DECL_MEMROTATE(type) \
void Q_GUI_EXPORT qt_memrotate90(const type*, int, int, int, type*, int); \
void Q_GUI_EXPORT qt_memrotate180(const type*, int, int, int, type*, int); \

View File

@ -2297,8 +2297,9 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
&& d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source)))
{
RotationType rotationType = qRotationType(s->matrix);
const QPixelLayout::BPP plBpp = qPixelLayouts[d->rasterBuffer->format].bpp;
if (rotationType != NoRotation && qMemRotateFunctions[d->rasterBuffer->format][rotationType] && img.rect().contains(sr.toAlignedRect())) {
if (rotationType != NoRotation && qMemRotateFunctions[plBpp][rotationType] && img.rect().contains(sr.toAlignedRect())) {
QRectF transformedTargetRect = s->matrix.mapRect(r);
if ((!(s->renderHints & QPainter::SmoothPixmapTransform) && !(s->renderHints & QPainter::Antialiasing))
@ -2328,7 +2329,7 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
uint cw = clippedSourceRect.width();
uint ch = clippedSourceRect.height();
qMemRotateFunctions[d->rasterBuffer->format][rotationType](srcBase, cw, ch, sbpl, dstBase, dbpl);
qMemRotateFunctions[plBpp][rotationType](srcBase, cw, ch, sbpl, dstBase, dbpl);
return;
}

View File

@ -1087,35 +1087,11 @@ void tst_QImage::rotate_data()
degrees << 0 << 90 << 180 << 270;
foreach (int d, degrees) {
const QByteArray dB = QByteArray::number(d);
QTest::newRow((dB + " Format_RGB32").constData())
<< QImage::Format_RGB32 << d;
QTest::newRow((dB + " Format_ARGB32").constData())
<< QImage::Format_ARGB32 << d;
QTest::newRow((dB + " Format_ARGB32_Premultiplied").constData())
<< QImage::Format_ARGB32_Premultiplied << d;
QTest::newRow((dB + " Format_RGB16").constData())
<< QImage::Format_RGB16 << d;
QTest::newRow((dB + " Format_ARGB8565_Premultiplied").constData())
<< QImage::Format_ARGB8565_Premultiplied << d;
QTest::newRow((dB + " Format_RGB666").constData())
<< QImage::Format_RGB666 << d;
QTest::newRow((dB + " Format_RGB555").constData())
<< QImage::Format_RGB555 << d;
QTest::newRow((dB + " Format_ARGB8555_Premultiplied").constData())
<< QImage::Format_ARGB8555_Premultiplied << d;
QTest::newRow((dB + " Format_RGB888").constData())
<< QImage::Format_RGB888 << d;
QTest::newRow((dB + " Format_Indexed8").constData())
<< QImage::Format_Indexed8 << d;
QTest::newRow((dB + " Format_RGBX8888").constData())
<< QImage::Format_RGBX8888 << d;
QTest::newRow((dB + " Format_RGBA8888_Premultiplied").constData())
<< QImage::Format_RGBA8888_Premultiplied << d;
QTest::newRow((dB + " Format_Alpha8").constData())
<< QImage::Format_Alpha8 << d;
QTest::newRow((dB + " Format_Grayscale8").constData())
<< QImage::Format_Grayscale8 << d;
const QString dB = QString::number(d);
for (int i = QImage::Format_Indexed8; i < QImage::NImageFormats; i++) {
QImage::Format format = static_cast<QImage::Format>(i);
QTest::newRow(qPrintable(dB + " " + formatToString(format))) << format << d;
}
}
}