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;
|
return src;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QImage rotated90(const QImage &image) {
|
static QImage rotated90(const QImage &image)
|
||||||
|
{
|
||||||
QImage out(image.height(), image.width(), image.format());
|
QImage out(image.height(), image.width(), image.format());
|
||||||
out.setDotsPerMeterX(image.dotsPerMeterY());
|
out.setDotsPerMeterX(image.dotsPerMeterY());
|
||||||
out.setDotsPerMeterY(image.dotsPerMeterX());
|
out.setDotsPerMeterY(image.dotsPerMeterX());
|
||||||
@ -4497,49 +4498,10 @@ static QImage rotated90(const QImage &image) {
|
|||||||
out.setColorTable(image.colorTable());
|
out.setColorTable(image.colorTable());
|
||||||
int w = image.width();
|
int w = image.width();
|
||||||
int h = image.height();
|
int h = image.height();
|
||||||
switch (image.format()) {
|
const MemRotateFunc memrotate = qMemRotateFunctions[qPixelLayouts[image.format()].bpp][2];
|
||||||
case QImage::Format_RGB32:
|
if (memrotate) {
|
||||||
case QImage::Format_ARGB32:
|
memrotate(image.constBits(), w, h, image.bytesPerLine(), out.bits(), out.bytesPerLine());
|
||||||
case QImage::Format_ARGB32_Premultiplied:
|
} else {
|
||||||
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:
|
|
||||||
for (int y=0; y<h; ++y) {
|
for (int y=0; y<h; ++y) {
|
||||||
if (image.colorCount())
|
if (image.colorCount())
|
||||||
for (int x=0; x<w; ++x)
|
for (int x=0; x<w; ++x)
|
||||||
@ -4548,18 +4510,29 @@ static QImage rotated90(const QImage &image) {
|
|||||||
for (int x=0; x<w; ++x)
|
for (int x=0; x<w; ++x)
|
||||||
out.setPixel(h-y-1, x, image.pixel(x, y));
|
out.setPixel(h-y-1, x, image.pixel(x, y));
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QImage rotated180(const QImage &image)
|
||||||
static QImage rotated180(const QImage &image) {
|
{
|
||||||
|
const MemRotateFunc memrotate = qMemRotateFunctions[qPixelLayouts[image.format()].bpp][1];
|
||||||
|
if (!memrotate)
|
||||||
return image.mirrored(true, true);
|
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());
|
QImage out(image.height(), image.width(), image.format());
|
||||||
out.setDotsPerMeterX(image.dotsPerMeterY());
|
out.setDotsPerMeterX(image.dotsPerMeterY());
|
||||||
out.setDotsPerMeterY(image.dotsPerMeterX());
|
out.setDotsPerMeterY(image.dotsPerMeterX());
|
||||||
@ -4567,49 +4540,10 @@ static QImage rotated270(const QImage &image) {
|
|||||||
out.setColorTable(image.colorTable());
|
out.setColorTable(image.colorTable());
|
||||||
int w = image.width();
|
int w = image.width();
|
||||||
int h = image.height();
|
int h = image.height();
|
||||||
switch (image.format()) {
|
const MemRotateFunc memrotate = qMemRotateFunctions[qPixelLayouts[image.format()].bpp][0];
|
||||||
case QImage::Format_RGB32:
|
if (memrotate) {
|
||||||
case QImage::Format_ARGB32:
|
memrotate(image.constBits(), w, h, image.bytesPerLine(), out.bits(), out.bytesPerLine());
|
||||||
case QImage::Format_ARGB32_Premultiplied:
|
} else {
|
||||||
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:
|
|
||||||
for (int y=0; y<h; ++y) {
|
for (int y=0; y<h; ++y) {
|
||||||
if (image.colorCount())
|
if (image.colorCount())
|
||||||
for (int x=0; x<w; ++x)
|
for (int x=0; x<w; ++x)
|
||||||
@ -4618,7 +4552,6 @@ static QImage rotated270(const QImage &image) {
|
|||||||
for (int x=0; x<w; ++x)
|
for (int x=0; x<w; ++x)
|
||||||
out.setPixel(y, w-x-1, image.pixel(x, y));
|
out.setPixel(y, w-x-1, image.pixel(x, y));
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,6 @@ struct DrawHelper {
|
|||||||
extern SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats];
|
extern SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats];
|
||||||
extern SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats];
|
extern SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats];
|
||||||
extern SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFormats];
|
extern SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFormats];
|
||||||
extern MemRotateFunc qMemRotateFunctions[QImage::NImageFormats][3];
|
|
||||||
|
|
||||||
extern DrawHelper qDrawHelper[QImage::NImageFormats];
|
extern DrawHelper qDrawHelper[QImage::NImageFormats];
|
||||||
|
|
||||||
@ -1226,6 +1225,7 @@ extern QPixelLayout qPixelLayouts[QImage::NImageFormats];
|
|||||||
extern const FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount];
|
extern const FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount];
|
||||||
extern StorePixelsFunc qStorePixels[QPixelLayout::BPPCount];
|
extern StorePixelsFunc qStorePixels[QPixelLayout::BPPCount];
|
||||||
|
|
||||||
|
extern MemRotateFunc qMemRotateFunctions[QPixelLayout::BPPCount][3];
|
||||||
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -41,162 +41,8 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
#if QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
|
|
||||||
static const int tileSize = 32;
|
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>
|
template <class T>
|
||||||
Q_STATIC_TEMPLATE_FUNCTION
|
Q_STATIC_TEMPLATE_FUNCTION
|
||||||
inline void qt_memrotate90_tiled(const T *src, int w, int h, int sstride, T *dest, int dstride)
|
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) {
|
for (int y = starty; y < stopy; y += pack) {
|
||||||
quint32 c = src[y * sstride + x];
|
quint32 c = src[y * sstride + x];
|
||||||
for (int i = 1; i < pack; ++i) {
|
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];
|
const T color = src[(y + i) * sstride + x];
|
||||||
c |= color << shift;
|
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 pack = sizeof(quint32) / sizeof(T);
|
||||||
const int unaligned =
|
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 restX = w % tileSize;
|
||||||
const int restY = (h - unaligned) % tileSize;
|
const int restY = (h - unaligned) % tileSize;
|
||||||
const int unoptimizedY = restY % pack;
|
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) {
|
for (int x = startx; x < stopx; ++x) {
|
||||||
quint32 *d = reinterpret_cast<quint32*>(dest + x * dstride
|
quint32 *d = reinterpret_cast<quint32*>(dest + x * dstride
|
||||||
+ h - 1 - starty);
|
+ 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];
|
quint32 c = src[y * sstride + x];
|
||||||
for (int i = 1; i < pack; ++i) {
|
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];
|
const T color = src[(y - i) * sstride + x];
|
||||||
c |= color << shift;
|
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>
|
template <class T>
|
||||||
Q_STATIC_TEMPLATE_FUNCTION
|
Q_STATIC_TEMPLATE_FUNCTION
|
||||||
inline void qt_memrotate90_template(const T *src, int srcWidth, int srcHeight, int srcStride,
|
inline void qt_memrotate90_template(const T *src, int srcWidth, int srcHeight, int srcStride,
|
||||||
T *dest, int dstStride)
|
T *dest, int dstStride)
|
||||||
{
|
{
|
||||||
#if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD
|
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||||
qt_memrotate90_cachedRead<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
|
// packed algorithm assumes little endian and that sizeof(quint32)/sizeof(T) is an integer
|
||||||
#elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
|
if (sizeof(quint32) % sizeof(T) == 0)
|
||||||
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);
|
qt_memrotate90_tiled<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
|
||||||
|
else
|
||||||
#endif
|
#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>
|
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)
|
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;
|
const char *s = (const char*)(src) + (h - 1) * sstride;
|
||||||
for (int y = h - 1; y >= 0; --y) {
|
for (int dy = 0; dy < h; ++dy) {
|
||||||
T *d = reinterpret_cast<T*>((char *)(dest) + (h - y - 1) * dstride);
|
T *d = reinterpret_cast<T*>((char *)(dest) + dy * dstride);
|
||||||
src = reinterpret_cast<const T*>(s);
|
src = reinterpret_cast<const T*>(s);
|
||||||
for (int x = w - 1; x >= 0; --x) {
|
for (int dx = 0; dx < w; ++dx) {
|
||||||
d[w - x - 1] = src[x];
|
d[dx] = src[w - 1 - dx];
|
||||||
}
|
}
|
||||||
s -= sstride;
|
s -= sstride;
|
||||||
}
|
}
|
||||||
@ -409,32 +259,20 @@ Q_STATIC_TEMPLATE_FUNCTION
|
|||||||
inline void qt_memrotate270_template(const T *src, int srcWidth, int srcHeight, int srcStride,
|
inline void qt_memrotate270_template(const T *src, int srcWidth, int srcHeight, int srcStride,
|
||||||
T *dest, int dstStride)
|
T *dest, int dstStride)
|
||||||
{
|
{
|
||||||
#if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD
|
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||||
qt_memrotate270_cachedRead<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
|
// packed algorithm assumes little endian and that sizeof(quint32)/sizeof(T) is an integer
|
||||||
#elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
|
if (sizeof(quint32) % sizeof(T) == 0)
|
||||||
qt_memrotate270_cachedWrite<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
|
qt_memrotate270_tiled<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
|
||||||
#elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING
|
else
|
||||||
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);
|
|
||||||
#endif
|
#endif
|
||||||
|
qt_memrotate270_tiled_unpacked<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline void qt_memrotate90_template<quint24>(const quint24 *src, int srcWidth, int srcHeight,
|
inline void qt_memrotate270_template<quint32>(const quint32 *src, int w, int h, int sstride, quint32 *dest, int dstride)
|
||||||
int srcStride, quint24 *dest, int dstStride)
|
|
||||||
{
|
{
|
||||||
#if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD
|
// packed algorithm doesn't have any benefit for quint32
|
||||||
qt_memrotate90_cachedRead<quint24>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
|
qt_memrotate270_tiled_unpacked(src, w, h, sstride, dest, dstride);
|
||||||
#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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define QT_IMPL_MEMROTATE(type) \
|
#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, \
|
Q_GUI_EXPORT void qt_memrotate90(const type *src, int w, int h, int sstride, \
|
||||||
type *dest, int dstride) \
|
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, \
|
Q_GUI_EXPORT void qt_memrotate180(const type *src, int w, int h, int sstride, \
|
||||||
type *dest, int dstride) \
|
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, \
|
Q_GUI_EXPORT void qt_memrotate270(const type *src, int w, int h, int sstride, \
|
||||||
type *dest, int dstride) \
|
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);
|
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)
|
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);
|
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);
|
qt_memrotate270((const uint *)srcPixels, w, h, sbpl, (uint *)destPixels, dbpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
MemRotateFunc qMemRotateFunctions[QImage::NImageFormats][3] =
|
MemRotateFunc qMemRotateFunctions[QPixelLayout::BPPCount][3] =
|
||||||
// 90, 180, 270
|
// 90, 180, 270
|
||||||
{
|
{
|
||||||
{ 0, 0, 0 }, // Format_Invalid,
|
{ 0, 0, 0 }, // BPPNone,
|
||||||
{ 0, 0, 0 }, // Format_Mono,
|
{ 0, 0, 0 }, // BPP1MSB,
|
||||||
{ 0, 0, 0 }, // Format_MonoLSB,
|
{ 0, 0, 0 }, // BPP1LSB,
|
||||||
{ 0, 0, 0 }, // Format_Indexed8,
|
{ qt_memrotate90_8, qt_memrotate180_8, qt_memrotate270_8 }, // BPP8,
|
||||||
{ qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_RGB32,
|
{ qt_memrotate90_16, qt_memrotate180_16, qt_memrotate270_16 }, // BPP16,
|
||||||
{ qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_ARGB32,
|
{ qt_memrotate90_24, qt_memrotate180_24, qt_memrotate270_24 }, // BPP24
|
||||||
{ qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_ARGB32_Premultiplied,
|
{ qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // BPP32
|
||||||
{ 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,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -56,19 +56,6 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
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) \
|
#define QT_DECL_MEMROTATE(type) \
|
||||||
void Q_GUI_EXPORT qt_memrotate90(const type*, int, int, int, type*, int); \
|
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); \
|
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)))
|
&& d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source)))
|
||||||
{
|
{
|
||||||
RotationType rotationType = qRotationType(s->matrix);
|
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);
|
QRectF transformedTargetRect = s->matrix.mapRect(r);
|
||||||
|
|
||||||
if ((!(s->renderHints & QPainter::SmoothPixmapTransform) && !(s->renderHints & QPainter::Antialiasing))
|
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 cw = clippedSourceRect.width();
|
||||||
uint ch = clippedSourceRect.height();
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1087,35 +1087,11 @@ void tst_QImage::rotate_data()
|
|||||||
degrees << 0 << 90 << 180 << 270;
|
degrees << 0 << 90 << 180 << 270;
|
||||||
|
|
||||||
foreach (int d, degrees) {
|
foreach (int d, degrees) {
|
||||||
const QByteArray dB = QByteArray::number(d);
|
const QString dB = QString::number(d);
|
||||||
QTest::newRow((dB + " Format_RGB32").constData())
|
for (int i = QImage::Format_Indexed8; i < QImage::NImageFormats; i++) {
|
||||||
<< QImage::Format_RGB32 << d;
|
QImage::Format format = static_cast<QImage::Format>(i);
|
||||||
QTest::newRow((dB + " Format_ARGB32").constData())
|
QTest::newRow(qPrintable(dB + " " + formatToString(format))) << format << d;
|
||||||
<< 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user