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:
parent
7a93d98f29
commit
7c401397a4
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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); \
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user