summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorKim Motoyoshi Kalland <kim.kalland@nokia.com>2012-01-13 12:07:11 +0100
committerQt by Nokia <qt-info@nokia.com>2012-02-07 15:52:01 +0100
commitba1cf5dae397031730fb77321db1807937e81617 (patch)
tree491f6eeeeba37dcb5764c0348ae4704c1e41c1e2 /src/gui
parentfe2344bd44e183b9893934d175c61a725af29b90 (diff)
Removed image format specific template functions in raster engine.
Simplified the raster engine by treating image formats in a more generic way and removed some unused code. Change-Id: Ib3979a1a6e3e6f17c5002248545779ec36fff7c9 Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/image/qimage.cpp511
-rw-r--r--src/gui/image/qpixmap_blitter.cpp26
-rw-r--r--src/gui/image/qpixmap_raster.cpp42
-rw-r--r--src/gui/painting/qblendfunctions.cpp208
-rw-r--r--src/gui/painting/qdrawhelper.cpp3828
-rw-r--r--src/gui/painting/qdrawhelper_neon.cpp2
-rw-r--r--src/gui/painting/qdrawhelper_p.h1361
-rw-r--r--src/gui/painting/qdrawhelper_sse2.cpp2
-rw-r--r--src/gui/painting/qdrawhelper_sse_p.h2
-rw-r--r--src/gui/painting/qmemrotate.cpp380
-rw-r--r--src/gui/painting/qmemrotate_p.h38
11 files changed, 1830 insertions, 4570 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 07af19d06a..5b23dbf4dc 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -74,30 +74,6 @@ static inline bool isLocked(QImageData *data)
return data != 0 && data->is_locked;
}
-static inline bool checkPixelSize(const QImage::Format format)
-{
- switch (format) {
- case QImage::Format_ARGB8565_Premultiplied:
- return (sizeof(qargb8565) == 3);
- case QImage::Format_RGB666:
- return (sizeof(qrgb666) == 3);
- case QImage::Format_ARGB6666_Premultiplied:
- return (sizeof(qargb6666) == 3);
- case QImage::Format_RGB555:
- return (sizeof(qrgb555) == 2);
- case QImage::Format_ARGB8555_Premultiplied:
- return (sizeof(qargb8555) == 3);
- case QImage::Format_RGB888:
- return (sizeof(qrgb888) == 3);
- case QImage::Format_RGB444:
- return (sizeof(qrgb444) == 2);
- case QImage::Format_ARGB4444_Premultiplied:
- return (sizeof(qargb4444) == 2);
- default:
- return true;
- }
-}
-
#if defined(Q_CC_DEC) && defined(__alpha) && (__DECCXX_VER-0 >= 50190001)
#pragma message disable narrowptr
#endif
@@ -141,12 +117,6 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format, int nu
if (!size.isValid() || numColors < 0 || format == QImage::Format_Invalid)
return 0; // invalid parameter(s)
- if (!checkPixelSize(format)) {
- qWarning("QImageData::create(): Invalid pixel size for format %i",
- format);
- return 0;
- }
-
uint width = size.width();
uint height = size.height();
uint depth = qt_depthForFormat(format);
@@ -793,12 +763,6 @@ QImageData *QImageData::create(uchar *data, int width, int height, int bpl, QIm
if (format == QImage::Format_Invalid)
return d;
- if (!checkPixelSize(format)) {
- qWarning("QImageData::create(): Invalid pixel size for format %i",
- format);
- return 0;
- }
-
const int depth = qt_depthForFormat(format);
const int calc_bytes_per_line = ((width * depth + 31)/32) * 4;
const int min_bytes_per_line = (width * depth + 7)/8;
@@ -1708,9 +1672,8 @@ void QImage::fill(const QColor &color)
pixel = PREMUL(pixel);
fill((uint) pixel);
- } else if (d->depth == 16 && d->format == QImage::Format_RGB16) {
- qrgb565 p(color.rgba());
- fill((uint) p.rawValue());
+ } else if (d->format == QImage::Format_RGB16) {
+ fill((uint) qConvertRgb32To16(color.rgba()));
} else if (d->depth == 1) {
if (color == Qt::color1)
@@ -2025,12 +1988,12 @@ static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConvers
quint16 colorTableRGB16[256];
if (data->colortable.isEmpty()) {
for (int i = 0; i < 256; ++i)
- colorTableRGB16[i] = qt_colorConvert<quint16, quint32>(qRgb(i, i, i), 0);
+ colorTableRGB16[i] = qConvertRgb32To16(qRgb(i, i, i));
} else {
// 1) convert the existing colors to RGB16
const int tableSize = data->colortable.size();
for (int i = 0; i < tableSize; ++i)
- colorTableRGB16[i] = qt_colorConvert<quint16, quint32>(data->colortable.at(i), 0);
+ colorTableRGB16[i] = qConvertRgb32To16(data->colortable.at(i));
data->colortable = QVector<QRgb>();
// 2) fill the rest of the table in case src_data > colortable.size()
@@ -2068,7 +2031,8 @@ static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFl
quint16 *dst_data = (quint16 *) data->data;
for (int i = 0; i < data->height; ++i) {
- qt_memconvert(dst_data, src_data, data->width);
+ for (int j = 0; j < data->width; ++j)
+ dst_data[j] = qConvertRgb32To16(src_data[j]);
src_data = (quint32 *) (((char*)src_data) + src_bytes_per_line);
dst_data = (quint16 *) (((char*)dst_data) + dst_bytes_per_line);
}
@@ -2878,60 +2842,33 @@ static void convert_Mono_to_Indexed8(QImageData *dest, const QImageData *src, Qt
}
}
-#define CONVERT_DECL(DST, SRC) \
- static void convert_##SRC##_to_##DST(QImageData *dest, \
- const QImageData *src, \
- Qt::ImageConversionFlags) \
- { \
- qt_rectconvert<DST, SRC>(reinterpret_cast<DST*>(dest->data), \
- reinterpret_cast<const SRC*>(src->data), \
- 0, 0, src->width, src->height, \
- dest->bytes_per_line, src->bytes_per_line); \
+// Cannot be used with indexed formats.
+static void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ const int buffer_size = 2048;
+ uint buffer[buffer_size];
+ const QPixelLayout *srcLayout = &qPixelLayouts[src->format];
+ const QPixelLayout *destLayout = &qPixelLayouts[dest->format];
+ const uchar *srcData = src->data;
+ uchar *destData = dest->data;
+
+ FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp];
+ StorePixelsFunc store = qStorePixels[destLayout->bpp];
+
+ for (int y = 0; y < src->height; ++y) {
+ int x = 0;
+ while (x < src->width) {
+ int l = qMin(src->width - x, buffer_size);
+ const uint *ptr = fetch(buffer, srcData, x, l);
+ ptr = srcLayout->convertToARGB32PM(buffer, ptr, l, srcLayout, 0);
+ ptr = destLayout->convertFromARGB32PM(buffer, ptr, l, destLayout, 0);
+ store(destData, ptr, x, l);
+ x += l;
+ }
+ srcData += src->bytes_per_line;
+ destData += dest->bytes_per_line;
}
-
-CONVERT_DECL(quint32, quint16)
-CONVERT_DECL(quint16, quint32)
-CONVERT_DECL(quint32, qargb8565)
-CONVERT_DECL(qargb8565, quint32)
-CONVERT_DECL(quint32, qrgb555)
-CONVERT_DECL(qrgb666, quint32)
-CONVERT_DECL(quint32, qrgb666)
-CONVERT_DECL(qargb6666, quint32)
-CONVERT_DECL(quint32, qargb6666)
-CONVERT_DECL(qrgb555, quint32)
-#if (defined(QT_QWS_DEPTH_15) && defined(QT_QWS_DEPTH_16))
-CONVERT_DECL(quint16, qrgb555)
-CONVERT_DECL(qrgb555, quint16)
-#endif
-CONVERT_DECL(quint32, qrgb888)
-CONVERT_DECL(qrgb888, quint32)
-CONVERT_DECL(quint32, qargb8555)
-CONVERT_DECL(qargb8555, quint32)
-CONVERT_DECL(quint32, qrgb444)
-CONVERT_DECL(qrgb444, quint32)
-CONVERT_DECL(quint32, qargb4444)
-CONVERT_DECL(qargb4444, quint32)
-#undef CONVERT_DECL
-#define CONVERT_PTR(DST, SRC) convert_##SRC##_to_##DST
-
-/*
- Format_Invalid,
- Format_Mono,
- Format_MonoLSB,
- Format_Indexed8,
- Format_RGB32,
- Format_ARGB32,
- Format_ARGB32_Premultiplied,
- Format_RGB16,
- Format_ARGB8565_Premultiplied,
- Format_RGB666,
- Format_ARGB6666_Premultiplied,
- Format_RGB555,
- Format_ARGB8555_Premultiplied,
- Format_RGB888
- Format_RGB444
- Format_ARGB4444_Premultiplied
-*/
+}
// first index source, second dest
@@ -3005,15 +2942,15 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
mask_alpha_converter,
mask_alpha_converter,
- CONVERT_PTR(quint16, quint32),
- CONVERT_PTR(qargb8565, quint32),
- CONVERT_PTR(qrgb666, quint32),
- CONVERT_PTR(qargb6666, quint32),
- CONVERT_PTR(qrgb555, quint32),
- CONVERT_PTR(qargb8555, quint32),
- CONVERT_PTR(qrgb888, quint32),
- CONVERT_PTR(qrgb444, quint32),
- CONVERT_PTR(qargb4444, quint32)
+ convert_generic,
+ convert_generic,
+ convert_generic,
+ convert_generic,
+ convert_generic,
+ convert_generic,
+ convert_generic,
+ convert_generic,
+ convert_generic
}, // Format_RGB32
{
@@ -3024,15 +2961,15 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
mask_alpha_converter,
0,
convert_ARGB_to_ARGB_PM,
- CONVERT_PTR(quint16, quint32),
- CONVERT_PTR(qargb8565, quint32),
- CONVERT_PTR(qrgb666, quint32),
- CONVERT_PTR(qargb6666, quint32),
- CONVERT_PTR(qrgb555, quint32),
- CONVERT_PTR(qargb8555, quint32),
- CONVERT_PTR(qrgb888, quint32),
- CONVERT_PTR(qrgb444, quint32),
- CONVERT_PTR(qargb4444, quint32)
+ convert_generic,
+ convert_generic,
+ convert_generic,
+ convert_generic,
+ convert_generic,
+ convert_generic,
+ convert_generic,
+ convert_generic,
+ convert_generic
}, // Format_ARGB32
{
@@ -3059,15 +2996,15 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- CONVERT_PTR(quint32, quint16),
- CONVERT_PTR(quint32, quint16),
- CONVERT_PTR(quint32, quint16),
+ convert_generic,
+ convert_generic,
+ convert_generic,
0,
0,
0,
0,
#if defined(QT_QWS_DEPTH_15) && defined(QT_QWS_DEPTH_16)
- CONVERT_PTR(qrgb555, quint16),
+ convert_generic,
#else
0,
#endif
@@ -3082,9 +3019,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- CONVERT_PTR(quint32, qargb8565),
- CONVERT_PTR(quint32, qargb8565),
- CONVERT_PTR(quint32, qargb8565),
+ convert_generic,
+ convert_generic,
+ convert_generic,
0,
0,
0,
@@ -3101,9 +3038,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- CONVERT_PTR(quint32, qrgb666),
- CONVERT_PTR(quint32, qrgb666),
- CONVERT_PTR(quint32, qrgb666),
+ convert_generic,
+ convert_generic,
+ convert_generic,
0,
0,
0,
@@ -3120,9 +3057,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- CONVERT_PTR(quint32, qargb6666),
- CONVERT_PTR(quint32, qargb6666),
- CONVERT_PTR(quint32, qargb6666),
+ convert_generic,
+ convert_generic,
+ convert_generic,
0,
0,
0,
@@ -3139,11 +3076,11 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- CONVERT_PTR(quint32, qrgb555),
- CONVERT_PTR(quint32, qrgb555),
- CONVERT_PTR(quint32, qrgb555),
+ convert_generic,
+ convert_generic,
+ convert_generic,
#if defined(QT_QWS_DEPTH_15) && defined(QT_QWS_DEPTH_16)
- CONVERT_PTR(quint16, qrgb555),
+ convert_generic,
#else
0,
#endif
@@ -3162,9 +3099,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- CONVERT_PTR(quint32, qargb8555),
- CONVERT_PTR(quint32, qargb8555),
- CONVERT_PTR(quint32, qargb8555),
+ convert_generic,
+ convert_generic,
+ convert_generic,
0,
0,
0,
@@ -3181,9 +3118,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- CONVERT_PTR(quint32, qrgb888),
- CONVERT_PTR(quint32, qrgb888),
- CONVERT_PTR(quint32, qrgb888),
+ convert_generic,
+ convert_generic,
+ convert_generic,
0,
0,
0,
@@ -3200,9 +3137,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- CONVERT_PTR(quint32, qrgb444),
- CONVERT_PTR(quint32, qrgb444),
- CONVERT_PTR(quint32, qrgb444),
+ convert_generic,
+ convert_generic,
+ convert_generic,
0,
0,
0,
@@ -3219,9 +3156,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- CONVERT_PTR(quint32, qargb4444),
- CONVERT_PTR(quint32, qargb4444),
- CONVERT_PTR(quint32, qargb4444),
+ convert_generic,
+ convert_generic,
+ convert_generic,
0,
0,
0,
@@ -3626,35 +3563,28 @@ QRgb QImage::pixel(int x, int y) const
qWarning("QImage::pixel: coordinate (%d,%d) out of range", x, y);
return 12345;
}
- const uchar * s = scanLine(y);
+
+ const uchar * s = constScanLine(y);
switch(d->format) {
case Format_Mono:
- return d->colortable.at((*(s + (x >> 3)) >> (7- (x & 7))) & 1);
+ return d->colortable.at((*(s + (x >> 3)) >> (~x & 7)) & 1);
case Format_MonoLSB:
return d->colortable.at((*(s + (x >> 3)) >> (x & 7)) & 1);
case Format_Indexed8:
return d->colortable.at((int)s[x]);
- case Format_ARGB8565_Premultiplied:
- return qt_colorConvert<quint32, qargb8565>(reinterpret_cast<const qargb8565*>(s)[x], 0);
- case Format_RGB666:
- return qt_colorConvert<quint32, qrgb666>(reinterpret_cast<const qrgb666*>(s)[x], 0);
- case Format_ARGB6666_Premultiplied:
- return qt_colorConvert<quint32, qargb6666>(reinterpret_cast<const qargb6666*>(s)[x], 0);
- case Format_RGB555:
- return qt_colorConvert<quint32, qrgb555>(reinterpret_cast<const qrgb555*>(s)[x], 0);
- case Format_ARGB8555_Premultiplied:
- return qt_colorConvert<quint32, qargb8555>(reinterpret_cast<const qargb8555*>(s)[x], 0);
- case Format_RGB888:
- return qt_colorConvert<quint32, qrgb888>(reinterpret_cast<const qrgb888*>(s)[x], 0);
- case Format_RGB444:
- return qt_colorConvert<quint32, qrgb444>(reinterpret_cast<const qrgb444*>(s)[x], 0);
- case Format_ARGB4444_Premultiplied:
- return qt_colorConvert<quint32, qargb4444>(reinterpret_cast<const qargb4444*>(s)[x], 0);
+ case Format_RGB32:
+ case Format_ARGB32: // Keep old behaviour.
+ case Format_ARGB32_Premultiplied:
+ return reinterpret_cast<const QRgb *>(s)[x];
case Format_RGB16:
- return qt_colorConvert<quint32, quint16>(reinterpret_cast<const quint16*>(s)[x], 0);
+ return qConvertRgb16To32(reinterpret_cast<const quint16 *>(s)[x]);
default:
- return ((QRgb*)s)[x];
+ break;
}
+ const QPixelLayout *layout = &qPixelLayouts[d->format];
+ uint result;
+ const uint *ptr = qFetchPixels[layout->bpp](&result, s, x, 1);
+ return *layout->convertToARGB32PM(&result, ptr, 1, layout, 0);
}
@@ -3693,7 +3623,6 @@ void QImage::setPixel(int x, int y, uint index_or_rgb)
}
// detach is called from within scanLine
uchar * s = scanLine(y);
- const quint32p p = quint32p::fromRawData(index_or_rgb);
switch(d->format) {
case Format_Mono:
case Format_MonoLSB:
@@ -3710,54 +3639,38 @@ void QImage::setPixel(int x, int y, uint index_or_rgb)
else
*(s + (x >> 3)) |= (1 << (7-(x & 7)));
}
- break;
+ return;
case Format_Indexed8:
if (index_or_rgb >= (uint)d->colortable.size()) {
qWarning("QImage::setPixel: Index %d out of range", index_or_rgb);
return;
}
s[x] = index_or_rgb;
- break;
+ return;
case Format_RGB32:
//make sure alpha is 255, we depend on it in qdrawhelper for cases
// when image is set as a texture pattern on a qbrush
((uint *)s)[x] = uint(255 << 24) | index_or_rgb;
- break;
+ return;
case Format_ARGB32:
case Format_ARGB32_Premultiplied:
((uint *)s)[x] = index_or_rgb;
- break;
+ return;
case Format_RGB16:
- ((quint16 *)s)[x] = qt_colorConvert<quint16, quint32p>(p, 0);
- break;
- case Format_ARGB8565_Premultiplied:
- ((qargb8565*)s)[x] = qt_colorConvert<qargb8565, quint32p>(p, 0);
- break;
- case Format_RGB666:
- ((qrgb666*)s)[x] = qt_colorConvert<qrgb666, quint32p>(p, 0);
- break;
- case Format_ARGB6666_Premultiplied:
- ((qargb6666*)s)[x] = qt_colorConvert<qargb6666, quint32p>(p, 0);
- break;
- case Format_RGB555:
- ((qrgb555*)s)[x] = qt_colorConvert<qrgb555, quint32p>(p, 0);
- break;
- case Format_ARGB8555_Premultiplied:
- ((qargb8555*)s)[x] = qt_colorConvert<qargb8555, quint32p>(p, 0);
- break;
- case Format_RGB888:
- ((qrgb888*)s)[x] = qt_colorConvert<qrgb888, quint32p>(p, 0);
- break;
- case Format_RGB444:
- ((qrgb444*)s)[x] = qt_colorConvert<qrgb444, quint32p>(p, 0);
- break;
- case Format_ARGB4444_Premultiplied:
- ((qargb4444*)s)[x] = qt_colorConvert<qargb4444, quint32p>(p, 0);
- break;
+ ((quint16 *)s)[x] = qConvertRgb32To16(INV_PREMUL(index_or_rgb));
+ return;
case Format_Invalid:
case NImageFormats:
Q_ASSERT(false);
+ return;
+ default:
+ break;
}
+
+ const QPixelLayout *layout = &qPixelLayouts[d->format];
+ uint result;
+ const uint *ptr = layout->convertFromARGB32PM(&result, &index_or_rgb, 1, layout, 0);
+ qStorePixels[layout->bpp](s, ptr, x, 1);
}
/*!
@@ -3774,30 +3687,56 @@ bool QImage::allGray() const
if (!d)
return true;
- if (d->depth == 32) {
- int p = width()*height();
- const QRgb* b = (const QRgb*)bits();
- while (p--)
- if (!qIsGray(*b++))
- return false;
- } else if (d->depth == 16) {
- int p = width()*height();
- const ushort* b = (const ushort *)bits();
- while (p--)
- if (!qIsGray(qt_colorConvert<quint32, quint16>(*b++, 0)))
- return false;
- } else if (d->format == QImage::Format_RGB888) {
- int p = width()*height();
- const qrgb888* b = (const qrgb888 *)bits();
- while (p--)
- if (!qIsGray(qt_colorConvert<quint32, qrgb888>(*b++, 0)))
- return false;
- } else {
- if (d->colortable.isEmpty())
- return true;
- for (int i = 0; i < colorCount(); i++)
+ switch (d->format) {
+ case Format_Mono:
+ case Format_MonoLSB:
+ case Format_Indexed8:
+ for (int i = 0; i < d->colortable.size(); ++i) {
if (!qIsGray(d->colortable.at(i)))
return false;
+ }
+ return true;
+ case Format_RGB32:
+ case Format_ARGB32:
+ case Format_ARGB32_Premultiplied:
+ for (int j = 0; j < d->height; ++j) {
+ const QRgb *b = (const QRgb *)constScanLine(j);
+ for (int i = 0; i < d->width; ++i) {
+ if (!qIsGray(b[i]))
+ return false;
+ }
+ }
+ return true;
+ case Format_RGB16:
+ for (int j = 0; j < d->height; ++j) {
+ const quint16 *b = (const quint16 *)constScanLine(j);
+ for (int i = 0; i < d->width; ++i) {
+ if (!qIsGray(qConvertRgb16To32(b[i])))
+ return false;
+ }
+ }
+ return true;
+ default:
+ break;
+ }
+
+ const int buffer_size = 2048;
+ uint buffer[buffer_size];
+ const QPixelLayout *layout = &qPixelLayouts[d->format];
+ FetchPixelsFunc fetch = qFetchPixels[layout->bpp];
+ for (int j = 0; j < d->height; ++j) {
+ const uchar *b = constScanLine(j);
+ int x = 0;
+ while (x < d->width) {
+ int l = qMin(d->width - x, buffer_size);
+ const uint *ptr = fetch(buffer, b, x, l);
+ ptr = layout->convertToARGB32PM(buffer, ptr, l, layout, 0);
+ for (int i = 0; i < l; ++i) {
+ if (!qIsGray(ptr[i]))
+ return false;
+ }
+ x += l;
+ }
}
return true;
}
@@ -4320,7 +4259,7 @@ QImage QImage::rgbSwapped() const
case Format_Invalid:
case NImageFormats:
Q_ASSERT(false);
- break;
+ return res;
case Format_Mono:
case Format_MonoLSB:
case Format_Indexed8:
@@ -4329,7 +4268,7 @@ QImage QImage::rgbSwapped() const
QRgb c = res.d->colortable.at(i);
res.d->colortable[i] = QRgb(((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00));
}
- break;
+ return res;
case Format_RGB32:
case Format_ARGB32:
case Format_ARGB32_Premultiplied:
@@ -4345,7 +4284,7 @@ QImage QImage::rgbSwapped() const
q++;
}
}
- break;
+ return res;
case Format_RGB16:
res = QImage(d->width, d->height, d->format);
QIMAGE_SANITYCHECK_MEMORY(res);
@@ -4359,113 +4298,41 @@ QImage QImage::rgbSwapped() const
q++;
}
}
+ return res;
+ default:
break;
- case Format_ARGB8565_Premultiplied:
- res = QImage(d->width, d->height, d->format);
- QIMAGE_SANITYCHECK_MEMORY(res);
- for (int i = 0; i < d->height; i++) {
- const quint8 *p = constScanLine(i);
- quint8 *q = res.scanLine(i);
- const quint8 *end = p + d->width * sizeof(qargb8565);
- while (p < end) {
- q[0] = p[0];
- q[1] = (p[1] & 0xe0) | (p[2] >> 3);
- q[2] = (p[2] & 0x07) | (p[1] << 3);
- p += sizeof(qargb8565);
- q += sizeof(qargb8565);
- }
- }
- break;
- case Format_RGB666:
- res = QImage(d->width, d->height, d->format);
- QIMAGE_SANITYCHECK_MEMORY(res);
- for (int i = 0; i < d->height; i++) {
- qrgb666 *q = reinterpret_cast<qrgb666*>(res.scanLine(i));
- const qrgb666 *p = reinterpret_cast<const qrgb666*>(constScanLine(i));
- const qrgb666 *end = p + d->width;
- while (p < end) {
- const QRgb rgb = quint32(*p++);
- *q++ = qRgb(qBlue(rgb), qGreen(rgb), qRed(rgb));
- }
- }
- break;
- case Format_ARGB6666_Premultiplied:
- res = QImage(d->width, d->height, d->format);
- QIMAGE_SANITYCHECK_MEMORY(res);
- for (int i = 0; i < d->height; i++) {
- const quint8 *p = constScanLine(i);
- const quint8 *end = p + d->width * sizeof(qargb6666);
- quint8 *q = res.scanLine(i);
- while (p < end) {
- q[0] = (p[1] >> 4) | ((p[2] & 0x3) << 4) | (p[0] & 0xc0);
- q[1] = (p[1] & 0xf) | (p[0] << 4);
- q[2] = (p[2] & 0xfc) | ((p[0] >> 4) & 0x3);
- p += sizeof(qargb6666);
- q += sizeof(qargb6666);
- }
- }
- break;
- case Format_RGB555:
- res = QImage(d->width, d->height, d->format);
- QIMAGE_SANITYCHECK_MEMORY(res);
- for (int i = 0; i < d->height; i++) {
- quint16 *q = (quint16*)res.scanLine(i);
- const quint16 *p = (const quint16*)constScanLine(i);
- const quint16 *end = p + d->width;
- while (p < end) {
- *q = ((*p << 10) & 0x7c00) | ((*p >> 10) & 0x1f) | (*p & 0x3e0);
- p++;
- q++;
- }
- }
- break;
- case Format_ARGB8555_Premultiplied:
- res = QImage(d->width, d->height, d->format);
- QIMAGE_SANITYCHECK_MEMORY(res);
- for (int i = 0; i < d->height; i++) {
- const quint8 *p = constScanLine(i);
- quint8 *q = res.scanLine(i);
- const quint8 *end = p + d->width * sizeof(qargb8555);
- while (p < end) {
- q[0] = p[0];
- q[1] = (p[1] & 0xe0) | (p[2] >> 2);
- q[2] = (p[2] & 0x03) | ((p[1] << 2) & 0x7f);
- p += sizeof(qargb8555);
- q += sizeof(qargb8555);
- }
- }
- break;
- case Format_RGB888:
- res = QImage(d->width, d->height, d->format);
- QIMAGE_SANITYCHECK_MEMORY(res);
- for (int i = 0; i < d->height; i++) {
- quint8 *q = res.scanLine(i);
- const quint8 *p = constScanLine(i);
- const quint8 *end = p + d->width * sizeof(qrgb888);
- while (p < end) {
- q[0] = p[2];
- q[1] = p[1];
- q[2] = p[0];
- q += sizeof(qrgb888);
- p += sizeof(qrgb888);
- }
- }
- break;
- case Format_RGB444:
- case Format_ARGB4444_Premultiplied:
- res = QImage(d->width, d->height, d->format);
- QIMAGE_SANITYCHECK_MEMORY(res);
- for (int i = 0; i < d->height; i++) {
- quint16 *q = reinterpret_cast<quint16*>(res.scanLine(i));
- const quint16 *p = reinterpret_cast<const quint16*>(constScanLine(i));
- const quint16 *end = p + d->width;
- while (p < end) {
- *q = (*p & 0xf0f0) | ((*p & 0x0f) << 8) | ((*p & 0xf00) >> 8);
- p++;
- q++;
+ }
+
+ res = QImage(d->width, d->height, d->format);
+ QIMAGE_SANITYCHECK_MEMORY(res);
+ const QPixelLayout *layout = &qPixelLayouts[d->format];
+ Q_ASSERT(layout->redWidth == layout->blueWidth);
+ FetchPixelsFunc fetch = qFetchPixels[layout->bpp];
+ StorePixelsFunc store = qStorePixels[layout->bpp];
+
+ const uint redBlueMask = (1 << layout->redWidth) - 1;
+ const uint alphaGreenMask = (((1 << layout->alphaWidth) - 1) << layout->alphaShift)
+ | (((1 << layout->greenWidth) - 1) << layout->greenShift);
+
+ const int buffer_size = 2048;
+ uint buffer[buffer_size];
+ for (int i = 0; i < d->height; ++i) {
+ uchar *q = res.scanLine(i);
+ const uchar *p = constScanLine(i);
+ int x = 0;
+ while (x < d->width) {
+ int l = qMin(d->width - x, buffer_size);
+ const uint *ptr = fetch(buffer, p, x, l);
+ for (int j = 0; j < l; ++j) {
+ uint red = (ptr[j] >> layout->redShift) & redBlueMask;
+ uint blue = (ptr[j] >> layout->blueShift) & redBlueMask;
+ buffer[j] = (ptr[j] & alphaGreenMask)
+ | (red << layout->blueShift)
+ | (blue << layout->redShift);
}
+ store(q, buffer, x, l);
+ x += l;
}
- break;
}
return res;
}
diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp
index e5222fa216..382c0b8d1a 100644
--- a/src/gui/image/qpixmap_blitter.cpp
+++ b/src/gui/image/qpixmap_blitter.cpp
@@ -144,27 +144,11 @@ void QBlittablePlatformPixmap::fill(const QColor &color)
m_alpha = true;
}
- uint pixel;
- switch (blittable()->lock()->format()) {
- case QImage::Format_ARGB32_Premultiplied:
- pixel = PREMUL(color.rgba());
- break;
- case QImage::Format_ARGB8565_Premultiplied:
- pixel = qargb8565(color.rgba()).rawValue();
- break;
- case QImage::Format_ARGB8555_Premultiplied:
- pixel = qargb8555(color.rgba()).rawValue();
- break;
- case QImage::Format_ARGB6666_Premultiplied:
- pixel = qargb6666(color.rgba()).rawValue();
- break;
- case QImage::Format_ARGB4444_Premultiplied:
- pixel = qargb4444(color.rgba()).rawValue();
- break;
- default:
- pixel = color.rgba();
- break;
- }
+ uint pixel = PREMUL(color.rgba());
+ const QPixelLayout *layout = &qPixelLayouts[blittable()->lock()->format()];
+ Q_ASSERT(layout->convertFromARGB32PM);
+ layout->convertFromARGB32PM(&pixel, &pixel, 1, layout, 0);
+
//so premultiplied formats are supported and ARGB32 and RGB32
blittable()->lock()->fill(pixel);
}
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index 3fe5216313..8125b1360d 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -202,46 +202,10 @@ void QRasterPlatformPixmap::fill(const QColor &color)
image = QImage(image.width(), image.height(), toFormat);
}
}
-
- switch (image.format()) {
- case QImage::Format_ARGB8565_Premultiplied:
- pixel = qargb8565(color.rgba()).rawValue();
- break;
- case QImage::Format_ARGB8555_Premultiplied:
- pixel = qargb8555(color.rgba()).rawValue();
- break;
- case QImage::Format_ARGB6666_Premultiplied:
- pixel = qargb6666(color.rgba()).rawValue();
- break;
- case QImage::Format_ARGB4444_Premultiplied:
- pixel = qargb4444(color.rgba()).rawValue();
- break;
- default:
- pixel = PREMUL(color.rgba());
- break;
- }
- } else {
- switch (image.format()) {
- case QImage::Format_RGB16:
- pixel = qt_colorConvert<quint16, quint32>(color.rgba(), 0);
- break;
- case QImage::Format_RGB444:
- pixel = qrgb444(color.rgba()).rawValue();
- break;
- case QImage::Format_RGB555:
- pixel = qrgb555(color.rgba()).rawValue();
- break;
- case QImage::Format_RGB666:
- pixel = qrgb666(color.rgba()).rawValue();
- break;
- case QImage::Format_RGB888:
- pixel = qrgb888(color.rgba()).rawValue();
- break;
- default:
- pixel = color.rgba();
- break;
- }
}
+ pixel = PREMUL(color.rgba());
+ const QPixelLayout *layout = &qPixelLayouts[image.format()];
+ layout->convertFromARGB32PM(&pixel, &pixel, 1, layout, 0);
} else {
pixel = 0;
// ### what about 8 bits
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index a83cadb161..f17a630c8d 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -71,21 +71,6 @@ struct SourceAndConstAlpha
RGB16 (565) format target format
************************************************************************/
-static inline quint16 convert_argb32_to_rgb16(quint32 spix)
-{
- quint32 b = spix;
- quint32 g = spix;
- b >>= 8;
- g >>= 5;
- b &= 0x0000f800;
- g &= 0x000007e0;
- spix >>= 3;
- b |= g;
- spix &= 0x0000001f;
- b |= spix;
- return b;
-}
-
struct Blend_RGB16_on_RGB16_NoAlpha {
inline void write(quint16 *dst, quint16 src) { *dst = src; }
@@ -108,46 +93,11 @@ struct Blend_RGB16_on_RGB16_ConstAlpha {
quint32 m_ialpha;
};
-struct Blend_ARGB24_on_RGB16_SourceAlpha {
- inline void write(quint16 *dst, const qargb8565 &src) {
- const uint alpha = src.alpha();
- if (alpha) {
- quint16 s = src.rawValue16();
- if (alpha < 255)
- s += BYTE_MUL_RGB16(*dst, 255 - alpha);
- *dst = s;
- }
- }
-
- inline void flush(void *) {}
-};
-
-struct Blend_ARGB24_on_RGB16_SourceAndConstAlpha {
- inline Blend_ARGB24_on_RGB16_SourceAndConstAlpha(quint32 alpha) {
- m_alpha = (alpha * 255) >> 8;
- }
-
- inline void write(quint16 *dst, qargb8565 src) {
- src = src.byte_mul(src.alpha(m_alpha));
- const uint alpha = src.alpha();
- if (alpha) {
- quint16 s = src.rawValue16();
- if (alpha < 255)
- s += BYTE_MUL_RGB16(*dst, 255 - alpha);
- *dst = s;
- }
- }
-
- inline void flush(void *) {}
-
- quint32 m_alpha;
-};
-
struct Blend_ARGB32_on_RGB16_SourceAlpha {
inline void write(quint16 *dst, quint32 src) {
const quint8 alpha = qAlpha(src);
- if(alpha) {
- quint16 s = convert_argb32_to_rgb16(src);
+ if (alpha) {
+ quint16 s = qConvertRgb32To16(src);
if(alpha < 255)
s += BYTE_MUL_RGB16(*dst, 255 - alpha);
*dst = s;
@@ -166,7 +116,7 @@ struct Blend_ARGB32_on_RGB16_SourceAndConstAlpha {
src = BYTE_MUL(src, m_alpha);
const quint8 alpha = qAlpha(src);
if(alpha) {
- quint16 s = convert_argb32_to_rgb16(src);
+ quint16 s = qConvertRgb32To16(src);
if(alpha < 255)
s += BYTE_MUL_RGB16(*dst, 255 - alpha);
*dst = s;
@@ -203,32 +153,6 @@ void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl,
}
}
-void qt_scale_image_argb24_on_rgb16(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- const QRectF &targetRect,
- const QRectF &sourceRect,
- const QRect &clip,
- int const_alpha)
-{
-#ifdef QT_DEBUG_DRAW
- printf("qt_scale_argb24_on_rgb16: dst=(%p, %d), src=(%p, %d), target=(%d, %d), [%d x %d], src=(%d, %d) [%d x %d] alpha=%d\n",
- destPixels, dbpl, srcPixels, sbpl,
- targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(),
- sourceRect.x(), sourceRect.y(), sourceRect.width(), sourceRect.height(),
- const_alpha);
-#endif
- if (const_alpha == 256) {
- Blend_ARGB24_on_RGB16_SourceAlpha noAlpha;
- qt_scale_image_16bit<qargb8565>(destPixels, dbpl, srcPixels, sbpl,
- targetRect, sourceRect, clip, noAlpha);
- } else {
- Blend_ARGB24_on_RGB16_SourceAndConstAlpha constAlpha(const_alpha);
- qt_scale_image_16bit<qargb8565>(destPixels, dbpl, srcPixels, sbpl,
- targetRect, sourceRect, clip, constAlpha);
- }
-}
-
-
void qt_scale_image_argb32_on_rgb16(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
const QRectF &targetRect,
@@ -280,7 +204,6 @@ void qt_blend_rgb16_on_rgb16(uchar *dst, int dbpl,
}
}
} else if (const_alpha != 0) {
- SourceAndConstAlpha alpha(const_alpha); // expects the 0-256 range
quint16 *d = (quint16 *) dst;
const quint16 *s = (const quint16 *) src;
quint8 a = (255 * const_alpha) >> 8;
@@ -296,79 +219,6 @@ void qt_blend_rgb16_on_rgb16(uchar *dst, int dbpl,
}
-template <typename T> void qt_blend_argb24_on_rgb16(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h, const T &alphaFunc)
-{
- int srcOffset = w*3;
- int dstJPL = dbpl / 2;
- quint16 *dst = (quint16 *) destPixels;
- int dstExtraStride = dstJPL - w;
-
- for (int y=0; y<h; ++y) {
- const uchar *src = srcPixels + y * sbpl;
- const uchar *srcEnd = src + srcOffset;
- while (src < srcEnd) {
-#if defined(QT_ARCH_ARMV5) || defined(QT_ARCH_POWERPC) || defined(QT_ARCH_SH) || defined(QT_ARCH_AVR32) || (defined(QT_ARCH_WINDOWSCE) && !defined(_X86_)) || (defined(QT_ARCH_SPARC) && defined(Q_CC_GNU)) || (defined(QT_ARCH_INTEGRITY) && !defined(_X86_))
- // non-16-bit aligned memory access is not possible on PowerPC,
- // ARM <v6 (QT_ARCH_ARMV5) & SH & AVR32 & SPARC w/GCC
- quint16 spix = (quint16(src[2])<<8) + src[1];
-#else
- quint16 spix = *(quint16 *) (src + 1);
-#endif
- uchar alpha = alphaFunc.alpha(*src);
-
- if (alpha == 255) {
- *dst = spix;
- } else if (alpha != 0) {
- quint16 dpix = *dst;
- quint32 sia = 255 - alpha;
-
- quint16 dr = (dpix & 0x0000f800);
- quint16 dg = (dpix & 0x000007e0);
- quint16 db = (dpix & 0x0000001f);
-
- quint32 siar = dr * sia;
- quint32 siag = dg * sia;
- quint32 siab = db * sia;
-
- quint32 rr = ((siar + (siar>>8) + (0x80 << 8)) >> 8) & 0xf800;
- quint32 rg = ((siag + (siag>>8) + (0x80 << 3)) >> 8) & 0x07e0;
- quint32 rb = ((siab + (siab>>8) + (0x80 >> 3)) >> 8) & 0x001f;
-
- *dst = alphaFunc.bytemul(spix) + rr + rg + rb;
- }
-
- ++dst;
- src += 3;
- }
- dst += dstExtraStride;
- }
-
-}
-
-static void qt_blend_argb24_on_rgb16(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha)
-{
-#ifdef QT_DEBUG_DRAW
- printf("qt_blend_argb24_on_rgb16: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
- destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
-#endif
-
- if (const_alpha != 256) {
- SourceAndConstAlpha alphaFunc(const_alpha);
- qt_blend_argb24_on_rgb16(destPixels, dbpl, srcPixels, sbpl, w, h, alphaFunc);
- } else {
- SourceOnlyAlpha alphaFunc;
- qt_blend_argb24_on_rgb16(destPixels, dbpl, srcPixels, sbpl, w, h, alphaFunc);
- }
-}
-
-
-
-
void qt_blend_argb32_on_rgb16_const_alpha(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
int w, int h,
@@ -383,7 +233,7 @@ void qt_blend_argb32_on_rgb16_const_alpha(uchar *destPixels, int dbpl,
uint s = src[i];
s = BYTE_MUL(s, const_alpha);
int alpha = qAlpha(s);
- s = convert_argb32_to_rgb16(s);
+ s = qConvertRgb32To16(s);
s += BYTE_MUL_RGB16(dst[i], 255 - alpha);
dst[i] = s;
}
@@ -412,7 +262,7 @@ static void qt_blend_argb32_on_rgb16(uchar *destPixels, int dbpl,
quint32 alpha = spix >> 24;
if (alpha == 255) {
- dst[x] = convert_argb32_to_rgb16(spix);
+ dst[x] = qConvertRgb32To16(spix);
} else if (alpha != 0) {
quint32 dpix = dst[x];
@@ -473,7 +323,7 @@ static void qt_blend_rgb32_on_rgb16(uchar *destPixels, int dbpl,
while (dst < dstEnd) {
const quint32 *srcEnd = src + w;
while (src < srcEnd) {
- *dst = convert_argb32_to_rgb16(*src);
+ *dst = qConvertRgb32To16(*src);
++dst;
++src;
}
@@ -545,19 +395,11 @@ void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl,
const uint *src = (const uint *) srcPixels;
uint *dst = (uint *) destPixels;
- if (w <= 64) {
- for (int y=0; y<h; ++y) {
- qt_memconvert(dst, src, w);
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
- } else {
- int len = w * 4;
- for (int y=0; y<h; ++y) {
- memcpy(dst, src, len);
- dst = (quint32 *)(((uchar *) dst) + dbpl);
- src = (const quint32 *)(((const uchar *) src) + sbpl);
- }
+ int len = w * 4;
+ for (int y=0; y<h; ++y) {
+ memcpy(dst, src, len);
+ dst = (quint32 *)(((uchar *) dst) + dbpl);
+ src = (const quint32 *)(((const uchar *) src) + sbpl);
}
}
@@ -681,28 +523,6 @@ void qt_transform_image_rgb16_on_rgb16(uchar *destPixels, int dbpl,
}
}
-void qt_transform_image_argb24_on_rgb16(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- const QRectF &targetRect,
- const QRectF &sourceRect,
- const QRect &clip,
- const QTransform &targetRectTransform,
- int const_alpha)
-{
- if (const_alpha == 256) {
- Blend_ARGB24_on_RGB16_SourceAlpha noAlpha;
- qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
- reinterpret_cast<const qargb8565 *>(srcPixels), sbpl,
- targetRect, sourceRect, clip, targetRectTransform, noAlpha);
- } else {
- Blend_ARGB24_on_RGB16_SourceAndConstAlpha constAlpha(const_alpha);
- qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
- reinterpret_cast<const qargb8565 *>(srcPixels), sbpl,
- targetRect, sourceRect, clip, targetRectTransform, constAlpha);
- }
-}
-
-
void qt_transform_image_argb32_on_rgb16(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
const QRectF &targetRect,
@@ -903,7 +723,7 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB32,
qt_scale_image_argb32_on_rgb16, // Format_ARGB32_Premultiplied,
qt_scale_image_rgb16_on_rgb16, // Format_RGB16,
- qt_scale_image_argb24_on_rgb16, // Format_ARGB8565_Premultiplied,
+ 0, // Format_ARGB8565_Premultiplied,
0, // Format_RGB666,
0, // Format_ARGB6666_Premultiplied,
0, // Format_RGB555,
@@ -1195,7 +1015,7 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] =
0, // Format_ARGB32,
qt_blend_argb32_on_rgb16, // Format_ARGB32_Premultiplied,
qt_blend_rgb16_on_rgb16, // Format_RGB16,
- qt_blend_argb24_on_rgb16, // Format_ARGB8565_Premultiplied,
+ 0, // Format_ARGB8565_Premultiplied,
0, // Format_RGB666,
0, // Format_ARGB6666_Premultiplied,
0, // Format_RGB555,
@@ -1486,7 +1306,7 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo
0, // Format_ARGB32,
qt_transform_image_argb32_on_rgb16, // Format_ARGB32_Premultiplied,
qt_transform_image_rgb16_on_rgb16, // Format_RGB16,
- qt_transform_image_argb24_on_rgb16, // Format_ARGB8565_Premultiplied,
+ 0, // Format_ARGB8565_Premultiplied,
0, // Format_RGB666,
0, // Format_ARGB6666_Premultiplied,
0, // Format_RGB555,
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 13b8c8cae5..6a34b5c7ca 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -79,6 +79,244 @@ enum {
// must be multiple of 4 for easier SIMD implementations
static const int buffer_size = 2048;
+
+
+
+// To convert in place, let 'dest' and 'src' be the same.
+static const uint *QT_FASTCALL convertIndexedToARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *clut)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = PREMUL(clut[src[i]]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertPassThrough(uint *, const uint *src, int,
+ const QPixelLayout *, const QRgb *)
+{
+ return src;
+}
+
+static const uint *QT_FASTCALL convertRGB16ToARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qConvertRgb16To32(src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = PREMUL(src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertToRGB32(uint *buffer, const uint *src, int count,
+ const QPixelLayout *layout, const QRgb *)
+{
+ Q_ASSERT(layout->redWidth >= 4);
+ Q_ASSERT(layout->greenWidth >= 4);
+ Q_ASSERT(layout->blueWidth >= 4);
+ Q_ASSERT(layout->alphaWidth == 0);
+
+ const uint redMask = ((1 << layout->redWidth) - 1);
+ const uint greenMask = ((1 << layout->greenWidth) - 1);
+ const uint blueMask = ((1 << layout->blueWidth) - 1);
+
+ const uchar redLeftShift = 8 - layout->redWidth;
+ const uchar greenLeftShift = 8 - layout->greenWidth;
+ const uchar blueLeftShift = 8 - layout->blueWidth;
+
+ const uchar redRightShift = 2 * layout->redWidth - 8;
+ const uchar greenRightShift = 2 * layout->greenWidth - 8;
+ const uchar blueRightShift = 2 * layout->blueWidth - 8;
+
+ for (int i = 0; i < count; ++i) {
+ uint red = (src[i] >> layout->redShift) & redMask;
+ uint green = (src[i] >> layout->greenShift) & greenMask;
+ uint blue = (src[i] >> layout->blueShift) & blueMask;
+
+ red = ((red << redLeftShift) | (red >> redRightShift)) << 16;
+ green = ((green << greenLeftShift) | (green >> greenRightShift)) << 8;
+ blue = (blue << blueLeftShift) | (blue >> blueRightShift);
+ buffer[i] = 0xff000000 | red | green | blue;
+ }
+
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertToARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *layout, const QRgb *)
+{
+ Q_ASSERT(layout->redWidth >= 4);
+ Q_ASSERT(layout->greenWidth >= 4);
+ Q_ASSERT(layout->blueWidth >= 4);
+ Q_ASSERT(layout->alphaWidth >= 4);
+
+ const uint redMask = ((1 << layout->redWidth) - 1);
+ const uint greenMask = ((1 << layout->greenWidth) - 1);
+ const uint blueMask = ((1 << layout->blueWidth) - 1);
+
+ const uchar redLeftShift = 8 - layout->redWidth;
+ const uchar greenLeftShift = 8 - layout->greenWidth;
+ const uchar blueLeftShift = 8 - layout->blueWidth;
+
+ const uchar redRightShift = 2 * layout->redWidth - 8;
+ const uchar greenRightShift = 2 * layout->greenWidth - 8;
+ const uchar blueRightShift = 2 * layout->blueWidth - 8;
+
+ const uint alphaMask = ((1 << layout->alphaWidth) - 1);
+ const uchar alphaLeftShift = 8 - layout->alphaWidth;
+ const uchar alphaRightShift = 2 * layout->alphaWidth - 8;
+
+ if (layout->premultiplied) {
+ for (int i = 0; i < count; ++i) {
+ uint alpha = (src[i] >> layout->alphaShift) & alphaMask;
+ uint red = (src[i] >> layout->redShift) & redMask;
+ uint green = (src[i] >> layout->greenShift) & greenMask;
+ uint blue = (src[i] >> layout->blueShift) & blueMask;
+
+ alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift);
+ red = qMin(alpha, (red << redLeftShift) | (red >> redRightShift));
+ green = qMin(alpha, (green << greenLeftShift) | (green >> greenRightShift));
+ blue = qMin(alpha, (blue << blueLeftShift) | (blue >> blueRightShift));
+ buffer[i] = (alpha << 24) | (red << 16) | (green << 8) | blue;
+ }
+ } else {
+ for (int i = 0; i < count; ++i) {
+ uint alpha = (src[i] >> layout->alphaShift) & alphaMask;
+ uint red = (src[i] >> layout->redShift) & redMask;
+ uint green = (src[i] >> layout->greenShift) & greenMask;
+ uint blue = (src[i] >> layout->blueShift) & blueMask;
+
+ alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift);
+ red = (red << redLeftShift) | (red >> redRightShift);
+ green = (green << greenLeftShift) | (green >> greenRightShift);
+ blue = (blue << blueLeftShift) | (blue >> blueRightShift);
+ buffer[i] = PREMUL((alpha << 24) | (red << 16) | (green << 8) | blue);
+ }
+ }
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGB16FromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qConvertRgb32To16(INV_PREMUL(src[i]));
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertARGB32FromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = INV_PREMUL(src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertFromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *layout, const QRgb *)
+{
+ Q_ASSERT(layout->redWidth <= 8);
+ Q_ASSERT(layout->greenWidth <= 8);
+ Q_ASSERT(layout->blueWidth <= 8);
+ Q_ASSERT(layout->alphaWidth <= 8);
+
+ const uint redMask = (1 << layout->redWidth) - 1;
+ const uint greenMask = (1 << layout->greenWidth) - 1;
+ const uint blueMask = (1 << layout->blueWidth) - 1;
+ const uint alphaMask = (1 << layout->alphaWidth) - 1;
+
+ const uchar redRightShift = 24 - layout->redWidth;
+ const uchar greenRightShift = 16 - layout->greenWidth;
+ const uchar blueRightShift = 8 - layout->blueWidth;
+ const uchar alphaRightShift = 32 - layout->alphaWidth;
+
+ if (!layout->premultiplied) {
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qAlpha(src[i]) == 255 ? src[i] : INV_PREMUL(src[i]);
+ src = buffer;
+ }
+ for (int i = 0; i < count; ++i) {
+ uint red = ((src[i] >> redRightShift) & redMask) << layout->redShift;
+ uint green = ((src[i] >> greenRightShift) & greenMask) << layout->greenShift;
+ uint blue = ((src[i] >> blueRightShift) & blueMask) << layout->blueShift;
+ uint alpha = ((src[i] >> alphaRightShift) & alphaMask) << layout->alphaShift;
+ buffer[i] = red | green | blue | alpha;
+ }
+ return buffer;
+}
+
+// Note:
+// convertToArgb32() assumes that no color channel is less than 4 bits.
+// convertFromArgb32() assumes that no color channel is more than 8 bits.
+// QImage::rgbSwapped() assumes that the red and blue color channels have the same number of bits.
+QPixelLayout qPixelLayouts[QImage::NImageFormats] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPPNone, 0, 0 }, // Format_Invalid
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1MSB, convertIndexedToARGB32PM, 0 }, // Format_Mono
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1LSB, convertIndexedToARGB32PM, 0 }, // Format_MonoLSB
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertIndexedToARGB32PM, 0 }, // Format_Indexed8
+ { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP32, convertPassThrough, convertPassThrough }, // Format_RGB32
+ { 8, 16, 8, 8, 8, 0, 8, 24, false, QPixelLayout::BPP32, convertARGB32ToARGB32PM, convertARGB32FromARGB32PM }, // Format_ARGB32
+ { 8, 16, 8, 8, 8, 0, 8, 24, true, QPixelLayout::BPP32, convertPassThrough, convertPassThrough }, // Format_ARGB32_Premultiplied
+ { 5, 11, 6, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertRGB16ToARGB32PM, convertRGB16FromARGB32PM }, // Format_RGB16
+ { 5, 19, 6, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB8565_Premultiplied
+ { 6, 12, 6, 6, 6, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM }, // Format_RGB666
+ { 6, 12, 6, 6, 6, 0, 6, 18, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB6666_Premultiplied
+ { 5, 10, 5, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM }, // Format_RGB555
+ { 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB8555_Premultiplied
+ { 8, 0, 8, 8, 8, 16, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM }, // Format_RGB888
+ { 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM }, // Format_RGB444
+ { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM } // Format_ARGB4444_Premultiplied
+};
+
+FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount] = {
+ 0, // BPPNone
+ fetchPixels<QPixelLayout::BPP1MSB>, // BPP1MSB
+ fetchPixels<QPixelLayout::BPP1LSB>, // BPP1LSB
+ fetchPixels<QPixelLayout::BPP8>, // BPP8
+ fetchPixels<QPixelLayout::BPP16>, // BPP16
+ fetchPixels<QPixelLayout::BPP24>, // BPP24
+ fetchPixels<QPixelLayout::BPP32> // BPP32
+};
+
+StorePixelsFunc qStorePixels[QPixelLayout::BPPCount] = {
+ 0, // BPPNone
+ storePixels<QPixelLayout::BPP1MSB>, // BPP1MSB
+ storePixels<QPixelLayout::BPP1LSB>, // BPP1LSB
+ storePixels<QPixelLayout::BPP8>, // BPP8
+ storePixels<QPixelLayout::BPP16>, // BPP16
+ storePixels<QPixelLayout::BPP24>, // BPP24
+ storePixels<QPixelLayout::BPP32> // BPP32
+};
+
+typedef uint (QT_FASTCALL *FetchPixelFunc)(const uchar *src, int index);
+typedef void (QT_FASTCALL *StorePixelFunc)(uchar *dest, int index, uint pixel);
+
+FetchPixelFunc qFetchPixel[QPixelLayout::BPPCount] = {
+ 0, // BPPNone
+ fetchPixel<QPixelLayout::BPP1MSB>, // BPP1MSB
+ fetchPixel<QPixelLayout::BPP1LSB>, // BPP1LSB
+ fetchPixel<QPixelLayout::BPP8>, // BPP8
+ fetchPixel<QPixelLayout::BPP16>, // BPP16
+ fetchPixel<QPixelLayout::BPP24>, // BPP24
+ fetchPixel<QPixelLayout::BPP32> // BPP32
+};
+
+StorePixelFunc qStorePixel[QPixelLayout::BPPCount] = {
+ 0, // BPPNone
+ storePixel<QPixelLayout::BPP1MSB>, // BPP1MSB
+ storePixel<QPixelLayout::BPP1LSB>, // BPP1LSB
+ storePixel<QPixelLayout::BPP8>, // BPP8
+ storePixel<QPixelLayout::BPP16>, // BPP16
+ storePixel<QPixelLayout::BPP24>, // BPP24
+ storePixel<QPixelLayout::BPP32> // BPP32
+};
+
+
/*
Destination fetch. This is simple as we don't have to do bounds checks or
transformations
@@ -110,14 +348,6 @@ static uint * QT_FASTCALL destFetchMonoLsb(uint *buffer, QRasterBuffer *rasterBu
return start;
}
-static uint * QT_FASTCALL destFetchARGB32(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length)
-{
- const uint *data = (const uint *)rasterBuffer->scanLine(y) + x;
- for (int i = 0; i < length; ++i)
- buffer[i] = PREMUL(data[i]);
- return buffer;
-}
-
static uint * QT_FASTCALL destFetchARGB32P(uint *, QRasterBuffer *rasterBuffer, int x, int y, int)
{
return (uint *)rasterBuffer->scanLine(y) + x;
@@ -131,37 +361,32 @@ static uint * QT_FASTCALL destFetchRGB16(uint *buffer, QRasterBuffer *rasterBuff
return buffer;
}
-template <class DST>
-Q_STATIC_TEMPLATE_FUNCTION uint * QT_FASTCALL destFetch(uint *buffer, QRasterBuffer *rasterBuffer,
- int x, int y, int length)
+static uint *QT_FASTCALL destFetch(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length)
{
- const DST *src = reinterpret_cast<DST*>(rasterBuffer->scanLine(y)) + x;
- quint32 *dest = reinterpret_cast<quint32*>(buffer);
- while (length--)
- *dest++ = *src++;
- return buffer;
+ const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
+ const uint *ptr = qFetchPixels[layout->bpp](buffer, rasterBuffer->scanLine(y), x, length);
+ return const_cast<uint *>(layout->convertToARGB32PM(buffer, ptr, length, layout, 0));
}
-# define SPANFUNC_POINTER_DESTFETCH(Arg) destFetch<Arg>
static DestFetchProc destFetchProc[QImage::NImageFormats] =
{
- 0, // Format_Invalid
- destFetchMono, // Format_Mono,
- destFetchMonoLsb, // Format_MonoLSB
- 0, // Format_Indexed8
- destFetchARGB32P, // Format_RGB32
- destFetchARGB32, // Format_ARGB32,
- destFetchARGB32P, // Format_ARGB32_Premultiplied
- destFetchRGB16, // Format_RGB16
- SPANFUNC_POINTER_DESTFETCH(qargb8565), // Format_ARGB8565_Premultiplied
- SPANFUNC_POINTER_DESTFETCH(qrgb666), // Format_RGB666
- SPANFUNC_POINTER_DESTFETCH(qargb6666), // Format_ARGB6666_Premultiplied
- SPANFUNC_POINTER_DESTFETCH(qrgb555), // Format_RGB555
- SPANFUNC_POINTER_DESTFETCH(qargb8555), // Format_ARGB8555_Premultiplied
- SPANFUNC_POINTER_DESTFETCH(qrgb888), // Format_RGB888
- SPANFUNC_POINTER_DESTFETCH(qrgb444), // Format_RGB444
- SPANFUNC_POINTER_DESTFETCH(qargb4444) // Format_ARGB4444_Premultiplied
+ 0, // Format_Invalid
+ destFetchMono, // Format_Mono,
+ destFetchMonoLsb, // Format_MonoLSB
+ 0, // Format_Indexed8
+ destFetchARGB32P, // Format_RGB32
+ destFetch, // Format_ARGB32,
+ destFetchARGB32P, // Format_ARGB32_Premultiplied
+ destFetchRGB16, // Format_RGB16
+ destFetch, // Format_ARGB8565_Premultiplied
+ destFetch, // Format_RGB666
+ destFetch, // Format_ARGB6666_Premultiplied
+ destFetch, // Format_RGB555
+ destFetch, // Format_ARGB8555_Premultiplied
+ destFetch, // Format_RGB888
+ destFetch, // Format_RGB444
+ destFetch // Format_ARGB4444_Premultiplied
};
/*
@@ -253,63 +478,47 @@ static void QT_FASTCALL destStoreMonoLsb(QRasterBuffer *rasterBuffer, int x, int
}
}
-static void QT_FASTCALL destStoreARGB32(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length)
-{
- uint *data = (uint *)rasterBuffer->scanLine(y) + x;
- for (int i = 0; i < length; ++i) {
- int p = buffer[i];
- int alpha = qAlpha(p);
- if (alpha == 255)
- data[i] = p;
- else if (alpha == 0)
- data[i] = 0;
- else {
- int inv_alpha = 0xff0000/qAlpha(buffer[i]);
- data[i] = (p & 0xff000000)
- | ((qRed(p)*inv_alpha) & 0xff0000)
- | (((qGreen(p)*inv_alpha) >> 8) & 0xff00)
- | ((qBlue(p)*inv_alpha) >> 16);
- }
- }
-}
-
static void QT_FASTCALL destStoreRGB16(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length)
{
quint16 *data = (quint16*)rasterBuffer->scanLine(y) + x;
- qt_memconvert<quint16, quint32>(data, buffer, length);
+ for (int i = 0; i < length; ++i)
+ data[i] = qConvertRgb32To16(buffer[i]);
}
-template <class DST>
-Q_STATIC_TEMPLATE_FUNCTION void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer,
- int x, int y,
- const uint *buffer, int length)
+static void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length)
{
- DST *dest = reinterpret_cast<DST*>(rasterBuffer->scanLine(y)) + x;
- const quint32p *src = reinterpret_cast<const quint32p*>(buffer);
- while (length--)
- *dest++ = DST(*src++);
+ uint buf[buffer_size];
+ const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
+ StorePixelsFunc store = qStorePixels[layout->bpp];
+ uchar *dest = rasterBuffer->scanLine(y);
+ while (length) {
+ int l = qMin(length, buffer_size);
+ const uint *ptr = layout->convertFromARGB32PM(buf, buffer, l, layout, 0);
+ store(dest, ptr, x, l);
+ length -= l;
+ buffer += l;
+ x += l;
+ }
}
-# define SPANFUNC_POINTER_DESTSTORE(DEST) destStore<DEST>
-
static DestStoreProc destStoreProc[QImage::NImageFormats] =
{
- 0, // Format_Invalid
- destStoreMono, // Format_Mono,
- destStoreMonoLsb, // Format_MonoLSB
- 0, // Format_Indexed8
- 0, // Format_RGB32
- destStoreARGB32, // Format_ARGB32,
- 0, // Format_ARGB32_Premultiplied
- destStoreRGB16, // Format_RGB16
- SPANFUNC_POINTER_DESTSTORE(qargb8565), // Format_ARGB8565_Premultiplied
- SPANFUNC_POINTER_DESTSTORE(qrgb666), // Format_RGB666
- SPANFUNC_POINTER_DESTSTORE(qargb6666), // Format_ARGB6666_Premultiplied
- SPANFUNC_POINTER_DESTSTORE(qrgb555), // Format_RGB555
- SPANFUNC_POINTER_DESTSTORE(qargb8555), // Format_ARGB8555_Premultiplied
- SPANFUNC_POINTER_DESTSTORE(qrgb888), // Format_RGB888
- SPANFUNC_POINTER_DESTSTORE(qrgb444), // Format_RGB444
- SPANFUNC_POINTER_DESTSTORE(qargb4444) // Format_ARGB4444_Premultiplied
+ 0, // Format_Invalid
+ destStoreMono, // Format_Mono,
+ destStoreMonoLsb, // Format_MonoLSB
+ 0, // Format_Indexed8
+ 0, // Format_RGB32
+ destStore, // Format_ARGB32,
+ 0, // Format_ARGB32_Premultiplied
+ destStoreRGB16, // Format_RGB16
+ destStore, // Format_ARGB8565_Premultiplied
+ destStore, // Format_RGB666
+ destStore, // Format_ARGB6666_Premultiplied
+ destStore, // Format_RGB555
+ destStore, // Format_ARGB8555_Premultiplied
+ destStore, // Format_RGB888
+ destStore, // Format_RGB444
+ destStore // Format_ARGB4444_Premultiplied
};
/*
@@ -327,218 +536,139 @@ static DestStoreProc destStoreProc[QImage::NImageFormats] =
The generic implementation does pixel by pixel fetches
*/
-template <QImage::Format format>
-Q_STATIC_TEMPLATE_FUNCTION uint QT_FASTCALL qt_fetchPixel(const uchar *scanLine, int x, const QVector<QRgb> *rgb);
-
-template<>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-uint QT_FASTCALL qt_fetchPixel<QImage::Format_Mono>(const uchar *scanLine,
- int x, const QVector<QRgb> *rgb)
-{
- bool pixel = scanLine[x>>3] & (0x80 >> (x & 7));
- if (rgb) return PREMUL(rgb->at(pixel ? 1 : 0));
- return pixel ? 0xff000000 : 0xffffffff;
-}
-
-template<>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-uint QT_FASTCALL qt_fetchPixel<QImage::Format_MonoLSB>(const uchar *scanLine,
- int x, const QVector<QRgb> *rgb)
-{
- bool pixel = scanLine[x>>3] & (0x1 << (x & 7));
- if (rgb) return PREMUL(rgb->at(pixel ? 1 : 0));
- return pixel ? 0xff000000 : 0xffffffff;
-}
-
-template<>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-uint QT_FASTCALL qt_fetchPixel<QImage::Format_Indexed8>(const uchar *scanLine,
- int x, const QVector<QRgb> *rgb)
-{
- return PREMUL(rgb->at(scanLine[x]));
-}
-
-template<>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB32>(const uchar *scanLine,
- int x, const QVector<QRgb> *)
-{
- return PREMUL(((const uint *)scanLine)[x]);
-}
-
-template<>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB32_Premultiplied>(const uchar *scanLine,
- int x, const QVector<QRgb> *)
-{
- return ((const uint *)scanLine)[x];
-}
-
-template<>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-uint QT_FASTCALL qt_fetchPixel<QImage::Format_RGB16>(const uchar *scanLine,
- int x, const QVector<QRgb> *)
-{
- return qConvertRgb16To32(((const ushort *)scanLine)[x]);
-}
-
-template<>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB8565_Premultiplied>(const uchar *scanLine,
- int x,
- const QVector<QRgb> *)
-{
- const qargb8565 color = reinterpret_cast<const qargb8565*>(scanLine)[x];
- return qt_colorConvert<quint32, qargb8565>(color, 0);
-}
+enum TextureBlendType {
+ BlendUntransformed,
+ BlendTiled,
+ BlendTransformed,
+ BlendTransformedTiled,
+ BlendTransformedBilinear,
+ BlendTransformedBilinearTiled,
+ NBlendTypes
+};
-template<>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-uint QT_FASTCALL qt_fetchPixel<QImage::Format_RGB666>(const uchar *scanLine,
- int x,
- const QVector<QRgb> *)
+static const uint *QT_FASTCALL fetchUntransformed(uint *buffer, const Operator *,
+ const QSpanData *data, int y, int x, int length)
{
- const qrgb666 color = reinterpret_cast<const qrgb666*>(scanLine)[x];
- return qt_colorConvert<quint32, qrgb666>(color, 0);
+ const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
+ const uint *ptr = qFetchPixels[layout->bpp](buffer, data->texture.scanLine(y), x, length);
+ const QRgb *clut = data->texture.colorTable ? data->texture.colorTable->constData() : 0;
+ return layout->convertToARGB32PM(buffer, ptr, length, layout, clut);
}
-template<>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB6666_Premultiplied>(const uchar *scanLine,
- int x,
- const QVector<QRgb> *)
+static const uint *QT_FASTCALL fetchUntransformedARGB32PM(uint *, const Operator *,
+ const QSpanData *data, int y, int x, int)
{
- const qargb6666 color = reinterpret_cast<const qargb6666*>(scanLine)[x];
- return qt_colorConvert<quint32, qargb6666>(color, 0);
+ const uchar *scanLine = data->texture.scanLine(y);
+ return ((const uint *)scanLine) + x;
}
-template<>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-uint QT_FASTCALL qt_fetchPixel<QImage::Format_RGB555>(const uchar *scanLine,
- int x,
- const QVector<QRgb> *)
+static const uint *QT_FASTCALL fetchUntransformedRGB16(uint *buffer, const Operator *,
+ const QSpanData *data, int y, int x,
+ int length)
{
- const qrgb555 color = reinterpret_cast<const qrgb555*>(scanLine)[x];
- return qt_colorConvert<quint32, qrgb555>(color, 0);
+ const quint16 *scanLine = (const quint16 *)data->texture.scanLine(y) + x;
+ for (int i = 0; i < length; ++i)
+ buffer[i] = qConvertRgb16To32(scanLine[i]);
+ return buffer;
}
-template<>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB8555_Premultiplied>(const uchar *scanLine,
- int x,
- const QVector<QRgb> *)
+// blendType is either BlendTransformed or BlendTransformedTiled
+template<TextureBlendType blendType>
+Q_STATIC_TEMPLATE_FUNCTION
+const uint *QT_FASTCALL fetchTransformedARGB32PM(uint *buffer, const Operator *, const QSpanData *data,
+ int y, int x, int length)
{
- const qargb8555 color = reinterpret_cast<const qargb8555*>(scanLine)[x];
- return qt_colorConvert<quint32, qargb8555>(color, 0);
-}
+ int image_width = data->texture.width;
+ int image_height = data->texture.height;
-template<>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-uint QT_FASTCALL qt_fetchPixel<QImage::Format_RGB888>(const uchar *scanLine,
- int x,
- const QVector<QRgb> *)
-{
- const qrgb888 color = reinterpret_cast<const qrgb888*>(scanLine)[x];
- return qt_colorConvert<quint32, qrgb888>(color, 0);
-}
+ const qreal cx = x + qreal(0.5);
+ const qreal cy = y + qreal(0.5);
-template<>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-uint QT_FASTCALL qt_fetchPixel<QImage::Format_RGB444>(const uchar *scanLine,
- int x,
- const QVector<QRgb> *)
-{
- const qrgb444 color = reinterpret_cast<const qrgb444*>(scanLine)[x];
- return qt_colorConvert<quint32, qrgb444>(color, 0);
-}
+ const uint *end = buffer + length;
+ uint *b = buffer;
+ if (data->fast_matrix) {
+ // The increment pr x in the scanline
+ int fdx = (int)(data->m11 * fixed_scale);
+ int fdy = (int)(data->m12 * fixed_scale);
-template<>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-uint QT_FASTCALL qt_fetchPixel<QImage::Format_ARGB4444_Premultiplied>(const uchar *scanLine,
- int x,
- const QVector<QRgb> *)
-{
- const qargb4444 color = reinterpret_cast<const qargb4444*>(scanLine)[x];
- return qt_colorConvert<quint32, qargb4444>(color, 0);
-}
+ int fx = int((data->m21 * cy
+ + data->m11 * cx + data->dx) * fixed_scale);
+ int fy = int((data->m22 * cy
+ + data->m12 * cx + data->dy) * fixed_scale);
-template<>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-uint QT_FASTCALL qt_fetchPixel<QImage::Format_Invalid>(const uchar *,
- int ,
- const QVector<QRgb> *)
-{
- return 0;
-}
+ while (b < end) {
+ int px = fx >> 16;
+ int py = fy >> 16;
-typedef uint (QT_FASTCALL *FetchPixelProc)(const uchar *scanLine, int x, const QVector<QRgb> *);
+ if (blendType == BlendTransformedTiled) {
+ px %= image_width;
+ py %= image_height;
+ if (px < 0) px += image_width;
+ if (py < 0) py += image_height;
+ } else {
+ px = qBound(0, px, image_width - 1);
+ py = qBound(0, py, image_height - 1);
+ }
+ *b = reinterpret_cast<const uint *>(data->texture.scanLine(py))[px];
-#define SPANFUNC_POINTER_FETCHPIXEL(Arg) qt_fetchPixel<QImage::Arg>
+ fx += fdx;
+ fy += fdy;
+ ++b;
+ }
+ } else {
+ const qreal fdx = data->m11;
+ const qreal fdy = data->m12;
+ const qreal fdw = data->m13;
+ qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
+ qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
+ qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
-static const FetchPixelProc fetchPixelProc[QImage::NImageFormats] =
-{
- 0,
- SPANFUNC_POINTER_FETCHPIXEL(Format_Mono),
- SPANFUNC_POINTER_FETCHPIXEL(Format_MonoLSB),
- SPANFUNC_POINTER_FETCHPIXEL(Format_Indexed8),
- SPANFUNC_POINTER_FETCHPIXEL(Format_ARGB32_Premultiplied),
- SPANFUNC_POINTER_FETCHPIXEL(Format_ARGB32),
- SPANFUNC_POINTER_FETCHPIXEL(Format_ARGB32_Premultiplied),
- SPANFUNC_POINTER_FETCHPIXEL(Format_RGB16),
- SPANFUNC_POINTER_FETCHPIXEL(Format_ARGB8565_Premultiplied),
- SPANFUNC_POINTER_FETCHPIXEL(Format_RGB666),
- SPANFUNC_POINTER_FETCHPIXEL(Format_ARGB6666_Premultiplied),
- SPANFUNC_POINTER_FETCHPIXEL(Format_RGB555),
- SPANFUNC_POINTER_FETCHPIXEL(Format_ARGB8555_Premultiplied),
- SPANFUNC_POINTER_FETCHPIXEL(Format_RGB888),
- SPANFUNC_POINTER_FETCHPIXEL(Format_RGB444),
- SPANFUNC_POINTER_FETCHPIXEL(Format_ARGB4444_Premultiplied)
-};
+ while (b < end) {
+ const qreal iw = fw == 0 ? 1 : 1 / fw;
+ const qreal tx = fx * iw;
+ const qreal ty = fy * iw;
+ int px = int(tx) - (tx < 0);
+ int py = int(ty) - (ty < 0);
-enum TextureBlendType {
- BlendUntransformed,
- BlendTiled,
- BlendTransformed,
- BlendTransformedTiled,
- BlendTransformedBilinear,
- BlendTransformedBilinearTiled,
- NBlendTypes
-};
+ if (blendType == BlendTransformedTiled) {
+ px %= image_width;
+ py %= image_height;
+ if (px < 0) px += image_width;
+ if (py < 0) py += image_height;
+ } else {
+ px = qBound(0, px, image_width - 1);
+ py = qBound(0, py, image_height - 1);
+ }
+ *b = reinterpret_cast<const uint *>(data->texture.scanLine(py))[px];
-template <QImage::Format format>
-Q_STATIC_TEMPLATE_FUNCTION const uint * QT_FASTCALL qt_fetchUntransformed(uint *buffer, const Operator *, const QSpanData *data,
- int y, int x, int length)
-{
- const uchar *scanLine = data->texture.scanLine(y);
- for (int i = 0; i < length; ++i)
- buffer[i] = qt_fetchPixel<format>(scanLine, x + i, data->texture.colorTable);
+ fx += fdx;
+ fy += fdy;
+ fw += fdw;
+ //force increment to avoid /0
+ if (!fw) {
+ fw += fdw;
+ }
+ ++b;
+ }
+ }
return buffer;
}
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION const uint * QT_FASTCALL
-qt_fetchUntransformed<QImage::Format_ARGB32_Premultiplied>(uint *, const Operator *,
- const QSpanData *data,
- int y, int x, int)
-{
- const uchar *scanLine = data->texture.scanLine(y);
- return ((const uint *)scanLine) + x;
-}
-
template<TextureBlendType blendType> /* either BlendTransformed or BlendTransformedTiled */
Q_STATIC_TEMPLATE_FUNCTION
-const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const QSpanData *data,
- int y, int x, int length)
+const uint *QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const QSpanData *data,
+ int y, int x, int length)
{
- FetchPixelProc fetch = fetchPixelProc[data->texture.format];
-
int image_width = data->texture.width;
int image_height = data->texture.height;
const qreal cx = x + qreal(0.5);
const qreal cy = y + qreal(0.5);
+ const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
+ FetchPixelFunc fetch = qFetchPixel[layout->bpp];
+
const uint *end = buffer + length;
uint *b = buffer;
if (data->fast_matrix) {
@@ -560,18 +690,12 @@ const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const
py %= image_height;
if (px < 0) px += image_width;
if (py < 0) py += image_height;
-
- const uchar *scanLine = data->texture.scanLine(py);
- *b = fetch(scanLine, px, data->texture.colorTable);
} else {
- if ((px < 0) || (px >= image_width)
- || (py < 0) || (py >= image_height)) {
- *b = uint(0);
- } else {
- const uchar *scanLine = data->texture.scanLine(py);
- *b = fetch(scanLine, px, data->texture.colorTable);
- }
+ px = qBound(0, px, image_width - 1);
+ py = qBound(0, py, image_height - 1);
}
+ *b = fetch(data->texture.scanLine(py), px);
+
fx += fdx;
fy += fdy;
++b;
@@ -597,18 +721,12 @@ const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const
py %= image_height;
if (px < 0) px += image_width;
if (py < 0) py += image_height;
-
- const uchar *scanLine = data->texture.scanLine(py);
- *b = fetch(scanLine, px, data->texture.colorTable);
} else {
- if ((px < 0) || (px >= image_width)
- || (py < 0) || (py >= image_height)) {
- *b = uint(0);
- } else {
- const uchar *scanLine = data->texture.scanLine(py);
- *b = fetch(scanLine, px, data->texture.colorTable);
- }
+ px = qBound(0, px, image_width - 1);
+ py = qBound(0, py, image_height - 1);
}
+ *b = fetch(data->texture.scanLine(py), px);
+
fx += fdx;
fy += fdy;
fw += fdw;
@@ -619,8 +737,8 @@ const uint * QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const
++b;
}
}
-
- return buffer;
+ const QRgb *clut = data->texture.colorTable ? data->texture.colorTable->constData() : 0;
+ return layout->convertToARGB32PM(buffer, buffer, length, layout, clut);
}
/** \internal
@@ -714,42 +832,42 @@ static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, i
#endif
template<TextureBlendType blendType>
-Q_STATIC_TEMPLATE_FUNCTION inline void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2)
-{
- if (blendType == BlendTransformedBilinearTiled) {
- v1 %= max;
- if (v1 < 0) v1 += max;
- v2 = v1 + 1;
- v2 %= max;
- } else {
- if (v1 < l1) {
- v2 = v1 = l1;
- } else if (v1 >= l2) {
- v2 = v1 = l2;
- } else {
- v2 = v1 + 1;
- }
- }
+void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2);
+template<>
+Q_STATIC_TEMPLATE_SPECIALIZATION
+inline void fetchTransformedBilinear_pixelBounds<BlendTransformedBilinearTiled>(int max, int, int, int &v1, int &v2)
+{
+ v1 %= max;
+ if (v1 < 0)
+ v1 += max;
+ v2 = v1 + 1;
+ if (v2 == max)
+ v2 = 0;
Q_ASSERT(v1 >= 0 && v1 < max);
Q_ASSERT(v2 >= 0 && v2 < max);
}
-template<TextureBlendType blendType, QImage::Format format> /* blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled */
-Q_STATIC_TEMPLATE_FUNCTION
-const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *, const QSpanData *data,
- int y, int x, int length)
+template<>
+Q_STATIC_TEMPLATE_SPECIALIZATION
+inline void fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(int, int l1, int l2, int &v1, int &v2)
{
-#ifdef Q_CC_RVCT // needed to avoid compiler crash in RVCT 2.2
- FetchPixelProc fetch;
- if (format != QImage::Format_Invalid)
- fetch = qt_fetchPixel<format>;
+ if (v1 < l1)
+ v2 = v1 = l1;
+ else if (v1 >= l2)
+ v2 = v1 = l2;
else
- fetch = fetchPixelProc[data->texture.format];
-#else
- FetchPixelProc fetch = (format != QImage::Format_Invalid) ? FetchPixelProc(qt_fetchPixel<format>) : fetchPixelProc[data->texture.format];
-#endif
+ v2 = v1 + 1;
+ Q_ASSERT(v1 >= l1 && v1 <= l2);
+ Q_ASSERT(v2 >= l1 && v2 <= l2);
+}
+template<TextureBlendType blendType> /* blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled */
+Q_STATIC_TEMPLATE_FUNCTION
+const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, const Operator *,
+ const QSpanData *data, int y, int x,
+ int length)
+{
int image_width = data->texture.width;
int image_height = data->texture.height;
@@ -780,8 +898,8 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
int y1 = (fy >> 16);
int y2;
fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
- const uchar *s1 = data->texture.scanLine(y1);
- const uchar *s2 = data->texture.scanLine(y2);
+ const uint *s1 = (const uint *)data->texture.scanLine(y1);
+ const uint *s2 = (const uint *)data->texture.scanLine(y2);
if (fdx <= fixed_scale && fdx > 0) { // scale up on X
int disty = (fy & 0x0000ffff) >> 8;
@@ -806,8 +924,8 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
lim = qMin(count, image_x2-x+1);
if (x < image_x1) {
Q_ASSERT(x <= image_x2);
- uint t = fetch(s1, image_x1, data->texture.colorTable);
- uint b = fetch(s2, image_x1, data->texture.colorTable);
+ uint t = s1[image_x1];
+ uint b = s2[image_x1];
quint32 rb = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
quint32 ag = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
do {
@@ -819,8 +937,7 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
}
}
- if (blendType != BlendTransformedBilinearTiled &&
- (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32)) {
+ if (blendType != BlendTransformedBilinearTiled) {
#if defined(QT_ALWAYS_HAVE_SSE2)
const __m128i disty_ = _mm_set1_epi16(disty);
const __m128i idisty_ = _mm_set1_epi16(idisty);
@@ -890,8 +1007,8 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
x = qMin(x, image_x2);
}
- uint t = fetch(s1, x, data->texture.colorTable);
- uint b = fetch(s2, x, data->texture.colorTable);
+ uint t = s1[x];
+ uint b = s2[x];
intermediate_buffer[0][f] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
intermediate_buffer[1][f] = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
@@ -918,18 +1035,18 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
int y1 = (fy >> 16);
int y2;
fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
- const uchar *s1 = data->texture.scanLine(y1);
- const uchar *s2 = data->texture.scanLine(y2);
+ const uint *s1 = (const uint *)data->texture.scanLine(y1);
+ const uint *s2 = (const uint *)data->texture.scanLine(y2);
int disty = (fy & 0x0000ffff) >> 8;
int idisty = 256 - disty;
while (b < end) {
int x1 = (fx >> 16);
int x2;
fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
- uint tl = fetch(s1, x1, data->texture.colorTable);
- uint tr = fetch(s1, x2, data->texture.colorTable);
- uint bl = fetch(s2, x1, data->texture.colorTable);
- uint br = fetch(s2, x2, data->texture.colorTable);
+ uint tl = s1[x1];
+ uint tr = s1[x2];
+ uint bl = s2[x1];
+ uint br = s2[x2];
int distx = (fx & 0x0000ffff) >> 8;
int idistx = 256 - distx;
@@ -945,13 +1062,11 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
int y1 = (fy >> 16);
int y2;
fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
- const uchar *s1 = data->texture.scanLine(y1);
- const uchar *s2 = data->texture.scanLine(y2);
+ const uint *s1 = (const uint *)data->texture.scanLine(y1);
+ const uint *s2 = (const uint *)data->texture.scanLine(y2);
int disty = (fy & 0x0000ffff) >> 12;
- if (blendType != BlendTransformedBilinearTiled &&
- (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32)) {
-
+ if (blendType != BlendTransformedBilinearTiled) {
#define BILINEAR_DOWNSCALE_BOUNDS_PROLOG \
while (b < end) { \
int x1 = (fx >> 16); \
@@ -959,10 +1074,10 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); \
if (x1 != x2) \
break; \
- uint tl = fetch(s1, x1, data->texture.colorTable); \
- uint tr = fetch(s1, x2, data->texture.colorTable); \
- uint bl = fetch(s2, x1, data->texture.colorTable); \
- uint br = fetch(s2, x2, data->texture.colorTable); \
+ uint tl = s1[x1]; \
+ uint tr = s1[x2]; \
+ uint bl = s2[x1]; \
+ uint br = s2[x2]; \
int distx = (fx & 0x0000ffff) >> 12; \
*b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); \
fx += fdx; \
@@ -1070,10 +1185,10 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
int x1 = (fx >> 16);
int x2;
fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
- uint tl = fetch(s1, x1, data->texture.colorTable);
- uint tr = fetch(s1, x2, data->texture.colorTable);
- uint bl = fetch(s2, x1, data->texture.colorTable);
- uint br = fetch(s2, x2, data->texture.colorTable);
+ uint tl = s1[x1];
+ uint tr = s1[x2];
+ uint bl = s2[x1];
+ uint br = s2[x2];
int distx = (fx & 0x0000ffff) >> 12;
*b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
fx += fdx;
@@ -1092,13 +1207,13 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
- const uchar *s1 = data->texture.scanLine(y1);
- const uchar *s2 = data->texture.scanLine(y2);
+ const uint *s1 = (const uint *)data->texture.scanLine(y1);
+ const uint *s2 = (const uint *)data->texture.scanLine(y2);
- uint tl = fetch(s1, x1, data->texture.colorTable);
- uint tr = fetch(s1, x2, data->texture.colorTable);
- uint bl = fetch(s2, x1, data->texture.colorTable);
- uint br = fetch(s2, x2, data->texture.colorTable);
+ uint tl = s1[x1];
+ uint tr = s1[x2];
+ uint bl = s2[x1];
+ uint br = s2[x2];
int distx = (fx & 0x0000ffff) >> 8;
int disty = (fy & 0x0000ffff) >> 8;
@@ -1124,13 +1239,13 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
- const uchar *s1 = data->texture.scanLine(y1);
- const uchar *s2 = data->texture.scanLine(y2);
+ const uint *s1 = (const uint *)data->texture.scanLine(y1);
+ const uint *s2 = (const uint *)data->texture.scanLine(y2);
- uint tl = fetch(s1, x1, data->texture.colorTable);
- uint tr = fetch(s1, x2, data->texture.colorTable);
- uint bl = fetch(s2, x1, data->texture.colorTable);
- uint br = fetch(s2, x2, data->texture.colorTable);
+ uint tl = s1[x1];
+ uint tr = s1[x2];
+ uint bl = s2[x1];
+ uint br = s2[x2];
int distx = (fx & 0x0000ffff) >> 12;
int disty = (fy & 0x0000ffff) >> 12;
@@ -1170,13 +1285,13 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
- const uchar *s1 = data->texture.scanLine(y1);
- const uchar *s2 = data->texture.scanLine(y2);
+ const uint *s1 = (const uint *)data->texture.scanLine(y1);
+ const uint *s2 = (const uint *)data->texture.scanLine(y2);
- uint tl = fetch(s1, x1, data->texture.colorTable);
- uint tr = fetch(s1, x2, data->texture.colorTable);
- uint bl = fetch(s2, x1, data->texture.colorTable);
- uint br = fetch(s2, x2, data->texture.colorTable);
+ uint tl = s1[x1];
+ uint tr = s1[x2];
+ uint bl = s2[x1];
+ uint br = s2[x2];
uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
@@ -1196,119 +1311,452 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
return buffer;
}
-#define SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Arg) qt_fetchUntransformed<QImage::Arg>
+// blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled
+template<TextureBlendType blendType>
+Q_STATIC_TEMPLATE_FUNCTION
+const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *,
+ const QSpanData *data, int y, int x, int length)
+{
+ const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
+ const QRgb *clut = data->texture.colorTable ? data->texture.colorTable->constData() : 0;
+
+ int image_width = data->texture.width;
+ int image_height = data->texture.height;
+
+ int image_x1 = data->texture.x1;
+ int image_y1 = data->texture.y1;
+ int image_x2 = data->texture.x2 - 1;
+ int image_y2 = data->texture.y2 - 1;
+
+ const qreal cx = x + qreal(0.5);
+ const qreal cy = y + qreal(0.5);
+
+ if (data->fast_matrix) {
+ // The increment pr x in the scanline
+ int fdx = (int)(data->m11 * fixed_scale);
+ int fdy = (int)(data->m12 * fixed_scale);
+
+ int fx = int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
+ int fy = int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
+
+ fx -= half_point;
+ fy -= half_point;
+
+ if (fdy == 0) { //simple scale, no rotation
+ int y1 = (fy >> 16);
+ int y2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
+ const uchar *s1 = data->texture.scanLine(y1);
+ const uchar *s2 = data->texture.scanLine(y2);
+
+ if (fdx <= fixed_scale && fdx > 0) { // scale up on X
+ int disty = (fy & 0x0000ffff) >> 8;
+ int idisty = 256 - disty;
+ int x = fx >> 16;
+
+ // The idea is first to do the interpolation between the row s1 and the row s2
+ // into an intermediate buffer, then we interpolate between two pixel of this buffer.
+ FetchPixelsFunc fetch = qFetchPixels[layout->bpp];
+ uint buf1[buffer_size + 2];
+ uint buf2[buffer_size + 2];
+ const uint *ptr1;
+ const uint *ptr2;
+
+ int count = qCeil(length * data->m11) + 2; //+1 for the last pixel to interpolate with, and +1 for rounding errors.
+ Q_ASSERT(count <= buffer_size + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case
+
+ if (blendType == BlendTransformedBilinearTiled) {
+ x %= image_width;
+ if (x < 0)
+ x += image_width;
+ int len1 = qMin(count, image_width - x);
+ int len2 = qMin(x, count - len1);
+
+ ptr1 = fetch(buf1, s1, x, len1);
+ ptr1 = layout->convertToARGB32PM(buf1, ptr1, len1, layout, clut);
+ ptr2 = fetch(buf2, s2, x, len1);
+ ptr2 = layout->convertToARGB32PM(buf2, ptr2, len1, layout, clut);
+ for (int i = 0; i < len1; ++i) {
+ uint t = ptr1[i];
+ uint b = ptr2[i];
+ buf1[i] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ buf2[i] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ }
+
+ if (len2) {
+ ptr1 = fetch(buf1 + len1, s1, 0, len2);
+ ptr1 = layout->convertToARGB32PM(buf1 + len1, ptr1, len2, layout, clut);
+ ptr2 = fetch(buf2 + len1, s2, 0, len2);
+ ptr2 = layout->convertToARGB32PM(buf2 + len1, ptr2, len2, layout, clut);
+ for (int i = 0; i < len2; ++i) {
+ uint t = ptr1[i];
+ uint b = ptr2[i];
+ buf1[i + len1] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ buf2[i + len1] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ }
+ }
+ for (int i = image_width; i < count; ++i) {
+ buf1[i] = buf1[i - image_width];
+ buf2[i] = buf2[i - image_width];
+ }
+ } else {
+ int start = qMax(x, image_x1);
+ int end = qMin(x + count, image_x2 + 1);
+ int len = qMax(1, end - start);
+ int leading = start - x;
+
+ ptr1 = fetch(buf1 + leading, s1, start, len);
+ ptr1 = layout->convertToARGB32PM(buf1 + leading, ptr1, len, layout, clut);
+ ptr2 = fetch(buf2 + leading, s2, start, len);
+ ptr2 = layout->convertToARGB32PM(buf2 + leading, ptr2, len, layout, clut);
+
+ for (int i = 0; i < len; ++i) {
+ uint t = ptr1[i];
+ uint b = ptr2[i];
+ buf1[i + leading] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ buf2[i + leading] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ }
+
+ for (int i = 0; i < leading; ++i) {
+ buf1[i] = buf1[leading];
+ buf2[i] = buf2[leading];
+ }
+ for (int i = leading + len; i < count; ++i) {
+ buf1[i] = buf1[i - 1];
+ buf2[i] = buf2[i - 1];
+ }
+ }
+
+ // Now interpolate the values from the intermediate_buffer to get the final result.
+ fx &= fixed_scale - 1;
+ Q_ASSERT((fx >> 16) == 0);
+ for (int i = 0; i < length; ++i) {
+ register int x1 = (fx >> 16);
+ register int x2 = x1 + 1;
+ Q_ASSERT(x1 >= 0);
+ Q_ASSERT(x2 < count);
+
+ register int distx = (fx & 0x0000ffff) >> 8;
+ register int idistx = 256 - distx;
+ int rb = ((buf1[x1] * idistx + buf1[x2] * distx) >> 8) & 0xff00ff;
+ int ag = (buf2[x1] * idistx + buf2[x2] * distx) & 0xff00ff00;
+ buffer[i] = rb | ag;
+ fx += fdx;
+ }
+ } else {
+ FetchPixelFunc fetch = qFetchPixel[layout->bpp];
+ uint buf1[buffer_size];
+ uint buf2[buffer_size];
+ uint *b = buffer;
+ while (length) {
+ int len = qMin(length, buffer_size / 2);
+ int fracX = fx;
+ for (int i = 0; i < len; ++i) {
+ int x1 = (fx >> 16);
+ int x2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
+
+ buf1[i * 2 + 0] = fetch(s1, x1);
+ buf1[i * 2 + 1] = fetch(s1, x2);
+ buf2[i * 2 + 0] = fetch(s2, x1);
+ buf2[i * 2 + 1] = fetch(s2, x2);
+
+ fx += fdx;
+ }
+ layout->convertToARGB32PM(buf1, buf1, len * 2, layout, clut);
+ layout->convertToARGB32PM(buf2, buf2, len * 2, layout, clut);
+
+ if ((fdx < 0 && fdx > -(fixed_scale / 8)) || fabs(data->m22) < (1./8.)) { // scale up more than 8x
+ int disty = (fy & 0x0000ffff) >> 8;
+ int idisty = 256 - disty;
+ for (int i = 0; i < len; ++i) {
+ uint tl = buf1[i * 2 + 0];
+ uint tr = buf1[i * 2 + 1];
+ uint bl = buf2[i * 2 + 0];
+ uint br = buf2[i * 2 + 1];
+ int distx = (fracX & 0x0000ffff) >> 8;
+ int idistx = 256 - distx;
+ uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
+ uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
+ b[i] = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+ fracX += fdx;
+ }
+ } else { //scale down
+ int disty = (fy & 0x0000ffff) >> 12;
+ for (int i = 0; i < len; ++i) {
+ uint tl = buf1[i * 2 + 0];
+ uint tr = buf1[i * 2 + 1];
+ uint bl = buf2[i * 2 + 0];
+ uint br = buf2[i * 2 + 1];
+ int distx = (fracX & 0x0000ffff) >> 12;
+ b[i] = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
+ fracX += fdx;
+ }
+ }
+ length -= len;
+ b += len;
+ }
+ }
+ } else { //rotation
+ FetchPixelFunc fetch = qFetchPixel[layout->bpp];
+ uint buf1[buffer_size];
+ uint buf2[buffer_size];
+ uint *b = buffer;
+
+ while (length) {
+ int len = qMin(length, buffer_size / 2);
+ int fracX = fx;
+ int fracY = fy;
+ for (int i = 0; i < len; ++i) {
+ int x1 = (fx >> 16);
+ int x2;
+ int y1 = (fy >> 16);
+ int y2;
+ fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
+ fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
+
+ const uchar *s1 = data->texture.scanLine(y1);
+ const uchar *s2 = data->texture.scanLine(y2);
+
+ buf1[i * 2 + 0] = fetch(s1, x1);
+ buf1[i * 2 + 1] = fetch(s1, x2);
+ buf2[i * 2 + 0] = fetch(s2, x1);
+ buf2[i * 2 + 1] = fetch(s2, x2);
+
+ fx += fdx;
+ fy += fdy;
+ }
+ layout->convertToARGB32PM(buf1, buf1, len * 2, layout, clut);
+ layout->convertToARGB32PM(buf2, buf2, len * 2, layout, clut);
+
+ if (fabs(data->m11) > 8 || fabs(data->m22) > 8) {
+ //if we are zooming more than 8 times, we use 8bit precision for the position.
+ for (int i = 0; i < len; ++i) {
+ uint tl = buf1[i * 2 + 0];
+ uint tr = buf1[i * 2 + 1];
+ uint bl = buf2[i * 2 + 0];
+ uint br = buf2[i * 2 + 1];
+
+ int distx = (fracX & 0x0000ffff) >> 8;
+ int disty = (fracY & 0x0000ffff) >> 8;
+ int idistx = 256 - distx;
+ int idisty = 256 - disty;
+
+ uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
+ uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
+ b[i] = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+ fracX += fdx;
+ fracY += fdy;
+ }
+ } else {
+ //we are zooming less than 8x, use 4bit precision
+ for (int i = 0; i < len; ++i) {
+ uint tl = buf1[i * 2 + 0];
+ uint tr = buf1[i * 2 + 1];
+ uint bl = buf2[i * 2 + 0];
+ uint br = buf2[i * 2 + 1];
+
+ int distx = (fracX & 0x0000ffff) >> 12;
+ int disty = (fracY & 0x0000ffff) >> 12;
+
+ b[i] = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
+ fracX += fdx;
+ fracY += fdy;
+ }
+ }
+
+ length -= len;
+ b += len;
+ }
+ }
+ } else {
+ const qreal fdx = data->m11;
+ const qreal fdy = data->m12;
+ const qreal fdw = data->m13;
+
+ qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
+ qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
+ qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
+
+ FetchPixelFunc fetch = qFetchPixel[layout->bpp];
+ uint buf1[buffer_size];
+ uint buf2[buffer_size];
+ uint *b = buffer;
+
+ int distxs[buffer_size / 2];
+ int distys[buffer_size / 2];
+
+ while (length) {
+ int len = qMin(length, buffer_size / 2);
+ for (int i = 0; i < len; ++i) {
+ const qreal iw = fw == 0 ? 1 : 1 / fw;
+ const qreal px = fx * iw - qreal(0.5);
+ const qreal py = fy * iw - qreal(0.5);
+
+ int x1 = int(px) - (px < 0);
+ int x2;
+ int y1 = int(py) - (py < 0);
+ int y2;
+
+ distxs[i] = int((px - x1) * 256);
+ distys[i] = int((py - y1) * 256);
+
+ fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
+ fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
+
+ const uchar *s1 = data->texture.scanLine(y1);
+ const uchar *s2 = data->texture.scanLine(y2);
+
+ buf1[i * 2 + 0] = fetch(s1, x1);
+ buf1[i * 2 + 1] = fetch(s1, x2);
+ buf2[i * 2 + 0] = fetch(s2, x1);
+ buf2[i * 2 + 1] = fetch(s2, x2);
+
+ fx += fdx;
+ fy += fdy;
+ fw += fdw;
+ //force increment to avoid /0
+ if (!fw)
+ fw += fdw;
+ }
+
+ layout->convertToARGB32PM(buf1, buf1, len * 2, layout, clut);
+ layout->convertToARGB32PM(buf2, buf2, len * 2, layout, clut);
+
+ for (int i = 0; i < len; ++i) {
+ int distx = distxs[i];
+ int disty = distys[i];
+ int idistx = 256 - distx;
+ int idisty = 256 - disty;
+
+ uint tl = buf1[i * 2 + 0];
+ uint tr = buf1[i * 2 + 1];
+ uint bl = buf2[i * 2 + 0];
+ uint br = buf2[i * 2 + 1];
+
+ uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
+ uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
+ b[i] = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+ }
+ length -= len;
+ b += len;
+ }
+ }
+
+ return buffer;
+}
static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = {
// Untransformed
{
0, // Invalid
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_Mono), // Mono
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_MonoLSB), // MonoLsb
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_Indexed8), // Indexed8
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB32_Premultiplied), // RGB32
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB32), // ARGB32
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB32_Premultiplied), // ARGB32_Premultiplied
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB16), // RGB16
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB8565_Premultiplied),// ARGB8565_Premultiplied
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB666), // RGB666
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB6666_Premultiplied),// ARGB6666_Premultiplied
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB555), // RGB555
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB8555_Premultiplied),// ARGB8555_Premultiplied
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB888), // RGB888
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB444), // RGB444
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB4444_Premultiplied) // ARGB4444_Premultiplied
+ fetchUntransformed, // Mono
+ fetchUntransformed, // MonoLsb
+ fetchUntransformed, // Indexed8
+ fetchUntransformedARGB32PM, // RGB32
+ fetchUntransformed, // ARGB32
+ fetchUntransformedARGB32PM, // ARGB32_Premultiplied
+ fetchUntransformedRGB16, // RGB16
+ fetchUntransformed, // ARGB8565_Premultiplied
+ fetchUntransformed, // RGB666
+ fetchUntransformed, // ARGB6666_Premultiplied
+ fetchUntransformed, // RGB555
+ fetchUntransformed, // ARGB8555_Premultiplied
+ fetchUntransformed, // RGB888
+ fetchUntransformed, // RGB444
+ fetchUntransformed // ARGB4444_Premultiplied
},
// Tiled
{
0, // Invalid
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_Mono), // Mono
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_MonoLSB), // MonoLsb
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_Indexed8), // Indexed8
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB32_Premultiplied), // RGB32
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB32), // ARGB32
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB32_Premultiplied), // ARGB32_Premultiplied
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB16), // RGB16
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB8565_Premultiplied),// ARGB8565_Premultiplied
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB666), // RGB666
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB6666_Premultiplied),// ARGB6666_Premultiplied
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB555), // RGB555
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB8555_Premultiplied),// ARGB8555_Premultiplied
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB888), // RGB888
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_RGB444), // RGB444
- SPANFUNC_POINTER_FETCHHUNTRANSFORMED(Format_ARGB4444_Premultiplied) // ARGB4444_Premultiplied
+ fetchUntransformed, // Mono
+ fetchUntransformed, // MonoLsb
+ fetchUntransformed, // Indexed8
+ fetchUntransformedARGB32PM, // RGB32
+ fetchUntransformed, // ARGB32
+ fetchUntransformedARGB32PM, // ARGB32_Premultiplied
+ fetchUntransformedRGB16, // RGB16
+ fetchUntransformed, // ARGB8565_Premultiplied
+ fetchUntransformed, // RGB666
+ fetchUntransformed, // ARGB6666_Premultiplied
+ fetchUntransformed, // RGB555
+ fetchUntransformed, // ARGB8555_Premultiplied
+ fetchUntransformed, // RGB888
+ fetchUntransformed, // RGB444
+ fetchUntransformed // ARGB4444_Premultiplied
},
// Transformed
{
0, // Invalid
- fetchTransformed<BlendTransformed>, // Mono
- fetchTransformed<BlendTransformed>, // MonoLsb
- fetchTransformed<BlendTransformed>, // Indexed8
- fetchTransformed<BlendTransformed>, // RGB32
- fetchTransformed<BlendTransformed>, // ARGB32
- fetchTransformed<BlendTransformed>, // ARGB32_Premultiplied
- fetchTransformed<BlendTransformed>, // RGB16
- fetchTransformed<BlendTransformed>, // ARGB8565_Premultiplied
- fetchTransformed<BlendTransformed>, // RGB666
- fetchTransformed<BlendTransformed>, // ARGB6666_Premultiplied
- fetchTransformed<BlendTransformed>, // RGB555
- fetchTransformed<BlendTransformed>, // ARGB8555_Premultiplied
- fetchTransformed<BlendTransformed>, // RGB888
- fetchTransformed<BlendTransformed>, // RGB444
- fetchTransformed<BlendTransformed>, // ARGB4444_Premultiplied
+ fetchTransformed<BlendTransformed>, // Mono
+ fetchTransformed<BlendTransformed>, // MonoLsb
+ fetchTransformed<BlendTransformed>, // Indexed8
+ fetchTransformedARGB32PM<BlendTransformed>, // RGB32
+ fetchTransformed<BlendTransformed>, // ARGB32
+ fetchTransformedARGB32PM<BlendTransformed>, // ARGB32_Premultiplied
+ fetchTransformed<BlendTransformed>, // RGB16
+ fetchTransformed<BlendTransformed>, // ARGB8565_Premultiplied
+ fetchTransformed<BlendTransformed>, // RGB666
+ fetchTransformed<BlendTransformed>, // ARGB6666_Premultiplied
+ fetchTransformed<BlendTransformed>, // RGB555
+ fetchTransformed<BlendTransformed>, // ARGB8555_Premultiplied
+ fetchTransformed<BlendTransformed>, // RGB888
+ fetchTransformed<BlendTransformed>, // RGB444
+ fetchTransformed<BlendTransformed>, // ARGB4444_Premultiplied
},
{
0, // TransformedTiled
- fetchTransformed<BlendTransformedTiled>, // Mono
- fetchTransformed<BlendTransformedTiled>, // MonoLsb
- fetchTransformed<BlendTransformedTiled>, // Indexed8
- fetchTransformed<BlendTransformedTiled>, // RGB32
- fetchTransformed<BlendTransformedTiled>, // ARGB32
- fetchTransformed<BlendTransformedTiled>, // ARGB32_Premultiplied
- fetchTransformed<BlendTransformedTiled>, // RGB16
- fetchTransformed<BlendTransformedTiled>, // ARGB8565_Premultiplied
- fetchTransformed<BlendTransformedTiled>, // RGB666
- fetchTransformed<BlendTransformedTiled>, // ARGB6666_Premultiplied
- fetchTransformed<BlendTransformedTiled>, // RGB555
- fetchTransformed<BlendTransformedTiled>, // ARGB8555_Premultiplied
- fetchTransformed<BlendTransformedTiled>, // RGB888
- fetchTransformed<BlendTransformedTiled>, // RGB444
- fetchTransformed<BlendTransformedTiled>, // ARGB4444_Premultiplied
+ fetchTransformed<BlendTransformedTiled>, // Mono
+ fetchTransformed<BlendTransformedTiled>, // MonoLsb
+ fetchTransformed<BlendTransformedTiled>, // Indexed8
+ fetchTransformedARGB32PM<BlendTransformedTiled>, // RGB32
+ fetchTransformed<BlendTransformedTiled>, // ARGB32
+ fetchTransformedARGB32PM<BlendTransformedTiled>, // ARGB32_Premultiplied
+ fetchTransformed<BlendTransformedTiled>, // RGB16
+ fetchTransformed<BlendTransformedTiled>, // ARGB8565_Premultiplied
+ fetchTransformed<BlendTransformedTiled>, // RGB666
+ fetchTransformed<BlendTransformedTiled>, // ARGB6666_Premultiplied
+ fetchTransformed<BlendTransformedTiled>, // RGB555
+ fetchTransformed<BlendTransformedTiled>, // ARGB8555_Premultiplied
+ fetchTransformed<BlendTransformedTiled>, // RGB888
+ fetchTransformed<BlendTransformedTiled>, // RGB444
+ fetchTransformed<BlendTransformedTiled>, // ARGB4444_Premultiplied
},
{
0, // Bilinear
- fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // Mono
- fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // MonoLsb
- fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // Indexed8
- fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_ARGB32_Premultiplied>, // RGB32
- fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_ARGB32>, // ARGB32
- fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_ARGB32_Premultiplied>, // ARGB32_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // RGB16
- fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // ARGB8565_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // RGB666
- fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // ARGB6666_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // RGB555
- fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // ARGB8555_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // RGB888
- fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid>, // RGB444
- fetchTransformedBilinear<BlendTransformedBilinear, QImage::Format_Invalid> // ARGB4444_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinear>, // Mono
+ fetchTransformedBilinear<BlendTransformedBilinear>, // MonoLsb
+ fetchTransformedBilinear<BlendTransformedBilinear>, // Indexed8
+ fetchTransformedBilinearARGB32PM<BlendTransformedBilinear>, // RGB32
+ fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB32
+ fetchTransformedBilinearARGB32PM<BlendTransformedBilinear>, // ARGB32_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinear>, // RGB16
+ fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB8565_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinear>, // RGB666
+ fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB6666_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinear>, // RGB555
+ fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB8555_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinear>, // RGB888
+ fetchTransformedBilinear<BlendTransformedBilinear>, // RGB444
+ fetchTransformedBilinear<BlendTransformedBilinear> // ARGB4444_Premultiplied
},
{
0, // BilinearTiled
- fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // Mono
- fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // MonoLsb
- fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // Indexed8
- fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_ARGB32_Premultiplied>, // RGB32
- fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_ARGB32>, // ARGB32
- fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_ARGB32_Premultiplied>, // ARGB32_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // RGB16
- fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // ARGB8565_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // RGB666
- fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // ARGB6666_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // RGB555
- fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // ARGB8555_Premultiplied
- fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // RGB888
- fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid>, // RGB444
- fetchTransformedBilinear<BlendTransformedBilinearTiled, QImage::Format_Invalid> // ARGB4444_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // Mono
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // MonoLsb
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // Indexed8
+ fetchTransformedBilinearARGB32PM<BlendTransformedBilinearTiled>, // RGB32
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB32
+ fetchTransformedBilinearARGB32PM<BlendTransformedBilinearTiled>, // ARGB32_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB16
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB8565_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB666
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB6666_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB555
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB8555_Premultiplied
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB888
+ fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB444
+ fetchTransformedBilinear<BlendTransformedBilinearTiled> // ARGB4444_Premultiplied
},
};
@@ -3274,26 +3722,6 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in
// -------------------- blend methods ---------------------
-enum SpanMethod {
- RegularSpans,
- CallbackSpans
-};
-
-#if !defined(Q_CC_SUN)
-static
-#endif
-void drawBufferSpan(QSpanData *data, const uint *buffer, int bufsize,
- int x, int y, int length, uint const_alpha)
-{
- Q_UNUSED(data);
- Q_UNUSED(buffer);
- Q_UNUSED(bufsize);
- Q_UNUSED(x);
- Q_UNUSED(y);
- Q_UNUSED(length);
- Q_UNUSED(const_alpha);
-}
-
#if !defined(Q_CC_SUN)
static
#endif
@@ -3349,55 +3777,6 @@ static void blend_color_argb(int count, const QSpan *spans, void *userData)
}
}
-template <class T>
-Q_STATIC_TEMPLATE_FUNCTION void blendColor(int count, const QSpan *spans, void *userData)
-{
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
- Operator op = getOperator(data, spans, count);
-
- if (op.mode == QPainter::CompositionMode_Source) {
- const T c = qt_colorConvert<T, quint32p>(quint32p::fromRawData(data->solid.color), 0);
- while (count--) {
- T *target = ((T*)data->rasterBuffer->scanLine(spans->y))
- + spans->x;
- if (spans->coverage == 255) {
- qt_memfill(target, c, spans->len);
- } else {
- const quint8 alpha = T::alpha(spans->coverage);
- const T color = c.byte_mul(alpha);
- const int ialpha = T::ialpha(spans->coverage);
- const T *end = target + spans->len;
- while (target < end) {
- *target = color + target->byte_mul(ialpha);
- ++target;
- }
- }
- ++spans;
- }
- return;
- }
-
- if (op.mode == QPainter::CompositionMode_SourceOver) {
- while (count--) {
- const quint32 color = BYTE_MUL(data->solid.color, spans->coverage);
- const T c = qt_colorConvert<T, quint32p>(quint32p::fromRawData(color), 0);
- const quint8 ialpha = T::alpha(qAlpha(~color));
- T *target = ((T*)data->rasterBuffer->scanLine(spans->y)) + spans->x;
- const T *end = target + spans->len;
- while (target != end) {
- *target = c + target->byte_mul(ialpha);
- ++target;
- }
- ++spans;
- }
- return;
- }
-
- blend_color_generic(count, spans, userData);
-}
-
-#define SPANFUNC_POINTER_BLENDCOLOR(DST) blendColor<DST>
-
static void blend_color_rgb16(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
@@ -3542,7 +3921,6 @@ struct QBlendBase
uint src_buffer[buffer_size];
};
-template <SpanMethod spanMethod>
class BlendSrcGeneric : public QBlendBase
{
public:
@@ -3553,38 +3931,30 @@ public:
const uint *fetch(int x, int y, int len)
{
- if (spanMethod == RegularSpans)
- dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, y, len) : buffer;
-
+ dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, y, len) : buffer;
return op.src_fetch(src_buffer, &op, data, y, x, len);
}
- void process(int x, int y, int len, int coverage, const uint *src, int offset)
+ void process(int, int, int len, int coverage, const uint *src, int offset)
{
- if (spanMethod == RegularSpans)
- op.func(dest + offset, src + offset, len, coverage);
- else
- drawBufferSpan(data, src + offset, len, x, y, len, coverage);
+ op.func(dest + offset, src + offset, len, coverage);
}
void store(int x, int y, int len)
{
- if (spanMethod == RegularSpans && op.dest_store) {
+ if (op.dest_store)
op.dest_store(data->rasterBuffer, x, y, dest, len);
- }
}
};
-template <SpanMethod spanMethod>
-Q_STATIC_TEMPLATE_FUNCTION void blend_src_generic(int count, const QSpan *spans, void *userData)
+static void blend_src_generic(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
- BlendSrcGeneric<spanMethod> blend(data, getOperator(data, spans, count));
+ BlendSrcGeneric blend(data, getOperator(data, spans, count));
handleSpans(count, spans, data, blend);
}
-template <SpanMethod spanMethod>
-Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_generic(int count, const QSpan *spans, void *userData)
+static void blend_untransformed_generic(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
@@ -3615,15 +3985,10 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_generic(int count, const QSp
while (length) {
int l = qMin(buffer_size, length);
const uint *src = op.src_fetch(src_buffer, &op, data, sy, sx, l);
- if (spanMethod == RegularSpans) {
- uint *dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
- op.func(dest, src, l, coverage);
- if (op.dest_store)
- op.dest_store(data->rasterBuffer, x, spans->y, dest, l);
- } else {
- drawBufferSpan(data, src, l, x, spans->y,
- l, coverage);
- }
+ uint *dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
+ op.func(dest, src, l, coverage);
+ if (op.dest_store)
+ op.dest_store(data->rasterBuffer, x, spans->y, dest, l);
x += l;
sx += l;
length -= l;
@@ -3634,13 +3999,12 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_generic(int count, const QSp
}
}
-template <SpanMethod spanMethod>
-Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_argb(int count, const QSpan *spans, void *userData)
+static void blend_untransformed_argb(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format != QImage::Format_ARGB32_Premultiplied
&& data->texture.format != QImage::Format_RGB32) {
- blend_untransformed_generic<spanMethod>(count, spans, userData);
+ blend_untransformed_generic(count, spans, userData);
return;
}
@@ -3667,13 +4031,8 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_untransformed_argb(int count, const QSpan
if (length > 0) {
const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;
const uint *src = (uint *)data->texture.scanLine(sy) + sx;
- if (spanMethod == RegularSpans) {
- uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x;
- op.func(dest, src, length, coverage);
- } else {
- drawBufferSpan(data, src, length, x,
- spans->y, length, coverage);
- }
+ uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x;
+ op.func(dest, src, length, coverage);
}
}
++spans;
@@ -3731,1167 +4090,19 @@ static inline void blend_sourceOver_rgb16_rgb16(quint16 *dest,
}
}
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline void madd_2(DST *dest, const quint16 alpha, const SRC *src)
-{
- Q_ASSERT((quintptr(dest) & 0x3) == 0);
- Q_ASSERT((quintptr(src) & 0x3) == 0);
- dest[0] = dest[0].byte_mul(alpha >> 8) + DST(src[0]);
- dest[1] = dest[1].byte_mul(alpha & 0xff) + DST(src[1]);
-}
-
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline void madd_4(DST *dest, const quint32 alpha, const SRC *src)
-{
- Q_ASSERT((quintptr(dest) & 0x3) == 0);
- Q_ASSERT((quintptr(src) & 0x3) == 0);
- dest[0] = dest[0].byte_mul(alpha >> 24) + DST(src[0]);
- dest[1] = dest[1].byte_mul((alpha >> 16) & 0xff) + DST(src[1]);
- dest[2] = dest[2].byte_mul((alpha >> 8) & 0xff) + DST(src[2]);
- dest[3] = dest[3].byte_mul(alpha & 0xff) + DST(src[3]);
-}
-
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline void madd_4(qargb8565 *dest, const quint32 a, const qargb8565 *src)
-{
- Q_ASSERT((quintptr(dest) & 0x3) == 0);
- Q_ASSERT((quintptr(src) & 0x3) == 0);
-
- const quint32 *src32 = reinterpret_cast<const quint32*>(src);
- quint32 *dest32 = reinterpret_cast<quint32*>(dest);
- quint32 x, y, t;
- quint8 a8;
-
- {
- x = dest32[0];
- y = src32[0];
-
- a8 = a >> 24;
-
- // a0,g0
- t = ((((x & 0x0007e0ff) * a8) >> 5) & 0x0007e0ff) + (y & 0x0007c0f8);
-
- // r0,b0
- t |= ((((x & 0x00f81f00) * a8) >> 5) & 0x00f81f00) + (y & 0x00f81f00);
-
- a8 = (a >> 16) & 0xff;
-
- // a1
- t |= ((((x & 0xff000000) >> 5) * a8) & 0xff000000) + (y & 0xf8000000);
-
- dest32[0] = t;
- }
- {
- x = dest32[1];
- y = src32[1];
-
- // r1,b1
- t = ((((x & 0x0000f81f) * a8) >> 5) & 0x0000f81f) + (y & 0x0000f81f);
-
- // g1
- t |= ((((x & 0x000007e0) * a8) >> 5) & 0x000007e0) + (y & 0x000007c0);
-
- a8 = (a >> 8) & 0xff;
-
- // a2
- t |= ((((x & 0x00ff0000) * a8) >> 5) & 0x00ff0000) + (y & 0x00f80000);
-
- {
- // rgb2
- quint16 x16 = (x >> 24) | ((dest32[2] & 0x000000ff) << 8);
- quint16 y16 = (y >> 24) | ((src32[2] & 0x000000ff) << 8);
- quint16 t16;
-
- t16 = ((((x16 & 0xf81f) * a8) >> 5) & 0xf81f) + (y16 & 0xf81f);
- t16 |= ((((x16 & 0x07e0) * a8) >> 5) & 0x07e0) + (y16 & 0x07c0);
-
- // rg2
- t |= ((t16 & 0x00ff) << 24);
-
- dest32[1] = t;
-
- x = dest32[2];
- y = src32[2];
-
- // gb2
- t = (t16 >> 8);
- }
- }
- {
- a8 = a & 0xff;
-
- // g3,a3
- t |= ((((x & 0x07e0ff00) * a8) >> 5) & 0x07e0ff00) + (y & 0x07c0f800);
-
- // r3,b3
- t |= ((((x & 0xf81f0000) >> 5) * a8) & 0xf81f0000)+ (y & 0xf81f0000);
-
- dest32[2] = t;
- }
-}
-#endif
-
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline void madd_4(qargb8555 *dest, const quint32 a, const qargb8555 *src)
-{
- Q_ASSERT((quintptr(dest) & 0x3) == 0);
- Q_ASSERT((quintptr(src) & 0x3) == 0);
-
- const quint32 *src32 = reinterpret_cast<const quint32*>(src);
- quint32 *dest32 = reinterpret_cast<quint32*>(dest);
- quint32 x, y, t;
- quint8 a8;
-
- {
- x = dest32[0];
- y = src32[0];
-
- a8 = a >> 24;
-
- // a0,g0
- t = ((((x & 0x0003e0ff) * a8) >> 5) & 0x0003e0ff) + (y & 0x0003e0f8);
-
- // r0,b0
- t |= ((((x & 0x007c1f00) * a8) >> 5) & 0x007c1f00) + (y & 0x007c1f00);
-
- a8 = (a >> 16) & 0xff;
-
- // a1
- t |= ((((x & 0xff000000) >> 5) * a8) & 0xff000000) + (y & 0xf8000000);
-
- dest32[0] = t;
- }
- {
- x = dest32[1];
- y = src32[1];
-
- // r1,b1
- t = ((((x & 0x00007c1f) * a8) >> 5) & 0x00007c1f) + (y & 0x00007c1f);
-
- // g1
- t |= ((((x & 0x000003e0) * a8) >> 5) & 0x000003e0) + (y & 0x000003e0);
-
- a8 = (a >> 8) & 0xff;
-
- // a2
- t |= ((((x & 0x00ff0000) * a8) >> 5) & 0x00ff0000) + (y & 0x00f80000);
-
- {
- // rgb2
- quint16 x16 = (x >> 24) | ((dest32[2] & 0x000000ff) << 8);
- quint16 y16 = (y >> 24) | ((src32[2] & 0x000000ff) << 8);
- quint16 t16;
-
- t16 = ((((x16 & 0x7c1f) * a8) >> 5) & 0x7c1f) + (y16 & 0x7c1f);
- t16 |= ((((x16 & 0x03e0) * a8) >> 5) & 0x03e0) + (y16 & 0x03e0);
-
- // rg2
- t |= ((t16 & 0x00ff) << 24);
-
- dest32[1] = t;
-
- x = dest32[2];
- y = src32[2];
-
- // gb2
- t = (t16 >> 8);
- }
- }
- {
- a8 = a & 0xff;
-
- // g3,a3
- t |= ((((x & 0x03e0ff00) * a8) >> 5) & 0x03e0ff00) + (y & 0x03e0f800);
-
- // r3,b3
- t |= ((((x & 0x7c1f0000) >> 5) * a8) & 0x7c1f0000)+ (y & 0x7c1f0000);
-
- dest32[2] = t;
- }
-}
-#endif
-
-template <class T>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint16 alpha_2(const T *src)
-{
- Q_ASSERT((quintptr(src) & 0x3) == 0);
-
- if (T::hasAlpha())
- return (src[0].alpha() << 8) | src[1].alpha();
- else
- return 0xffff;
-}
-
-template <class T>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint32 alpha_4(const T *src)
-{
- Q_ASSERT((quintptr(src) & 0x3) == 0);
-
- if (T::hasAlpha()) {
- return (src[0].alpha() << 24) | (src[1].alpha() << 16)
- | (src[2].alpha() << 8) | src[3].alpha();
- } else {
- return 0xffffffff;
- }
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint32 alpha_4(const qargb8565 *src)
-{
- const quint8 *src8 = reinterpret_cast<const quint8*>(src);
- return src8[0] << 24 | src8[3] << 16 | src8[6] << 8 | src8[9];
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint32 alpha_4(const qargb6666 *src)
-{
- const quint8 *src8 = reinterpret_cast<const quint8*>(src);
- return ((src8[2] & 0xfc) | (src8[2] >> 6)) << 24
- | ((src8[5] & 0xfc) | (src8[5] >> 6)) << 16
- | ((src8[8] & 0xfc) | (src8[8] >> 6)) << 8
- | ((src8[11] & 0xfc) | (src8[11] >> 6));
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint32 alpha_4(const qargb8555 *src)
-{
- Q_ASSERT((quintptr(src) & 0x3) == 0);
- const quint8 *src8 = reinterpret_cast<const quint8*>(src);
- return src8[0] << 24 | src8[3] << 16 | src8[6] << 8 | src8[9];
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint16 alpha_2(const qargb4444 *src)
-{
- const quint32 *src32 = reinterpret_cast<const quint32*>(src);
- const quint32 t = (*src32 & 0xf000f000) |
- ((*src32 & 0xf000f000) >> 4);
- return (t >> 24) | (t & 0xff00);
-}
-
-template <class T>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint16 eff_alpha_2(quint16 alpha, const T*)
-{
- return (T::alpha((alpha >> 8) & 0xff) << 8)
- | T::alpha(alpha & 0xff);
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint16 eff_alpha_2(quint16 a, const qrgb565*)
-{
- return ((((a & 0xff00) + 0x0100) >> 3) & 0xff00)
- | ((((a & 0x00ff) + 0x0001) >> 3) & 0x00ff);
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint16 eff_alpha_2(quint16 a, const qrgb444*)
-{
- return (((a & 0x00ff) + 0x0001) >> 4)
- | ((((a & 0xff00) + 0x0100) >> 4) & 0xff00);
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint16 eff_alpha_2(quint16 a, const qargb4444*)
-{
- return (((a & 0x00ff) + 0x0001) >> 4)
- | ((((a & 0xff00) + 0x0100) >> 4) & 0xff00);
-}
-
-template <class T>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint16 eff_ialpha_2(quint16 alpha, const T*)
-{
- return (T::ialpha((alpha >> 8) & 0xff) << 8)
- | T::ialpha(alpha & 0xff);
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint16 eff_ialpha_2(quint16 a, const qrgb565 *dummy)
-{
- return 0x2020 - eff_alpha_2(a, dummy);
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint16 eff_ialpha_2(quint16 a, const qargb4444 *dummy)
-{
- return 0x1010 - eff_alpha_2(a, dummy);
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint16 eff_ialpha_2(quint16 a, const qrgb444 *dummy)
-{
- return 0x1010 - eff_alpha_2(a, dummy);
-}
-
-template <class T>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint32 eff_alpha_4(quint32 alpha, const T*)
-{
- return (T::alpha(alpha >> 24) << 24)
- | (T::alpha((alpha >> 16) & 0xff) << 16)
- | (T::alpha((alpha >> 8) & 0xff) << 8)
- | T::alpha(alpha & 0xff);
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint32 eff_alpha_4(quint32 a, const qrgb888*)
-{
- return a;
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint32 eff_alpha_4(quint32 a, const qargb8565*)
-{
- return ((((a & 0xff00ff00) + 0x01000100) >> 3) & 0xff00ff00)
- | ((((a & 0x00ff00ff) + 0x00010001) >> 3) & 0x00ff00ff);
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint32 eff_alpha_4(quint32 a, const qargb6666*)
-{
- return ((((a & 0xff00ff00) >> 2) + 0x00400040) & 0xff00ff00)
- | ((((a & 0x00ff00ff) + 0x00010001) >> 2) & 0x00ff00ff);
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint32 eff_alpha_4(quint32 a, const qrgb666*)
-{
- return ((((a & 0xff00ff00) >> 2) + 0x00400040) & 0xff00ff00)
- | ((((a & 0x00ff00ff) + 0x00010001) >> 2) & 0x00ff00ff);
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint32 eff_alpha_4(quint32 a, const qargb8555*)
-{
- return ((((a & 0xff00ff00) + 0x01000100) >> 3) & 0xff00ff00)
- | ((((a & 0x00ff00ff) + 0x00010001) >> 3) & 0x00ff00ff);
-}
-
-template <class T>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint32 eff_ialpha_4(quint32 alpha, const T*)
-{
- return (T::ialpha(alpha >> 24) << 24)
- | (T::ialpha((alpha >> 16) & 0xff) << 16)
- | (T::ialpha((alpha >> 8) & 0xff) << 8)
- | T::ialpha(alpha & 0xff);
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint32 eff_ialpha_4(quint32 a, const qrgb888*)
-{
- return ~a;
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint32 eff_ialpha_4(quint32 a, const qargb8565 *dummy)
-{
- return 0x20202020 - eff_alpha_4(a, dummy);
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint32 eff_ialpha_4(quint32 a, const qargb6666 *dummy)
-{
- return 0x40404040 - eff_alpha_4(a, dummy);
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint32 eff_ialpha_4(quint32 a, const qrgb666 *dummy)
-{
- return 0x40404040 - eff_alpha_4(a, dummy);
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline quint32 eff_ialpha_4(quint32 a, const qargb8555 *dummy)
-{
- return 0x20202020 - eff_alpha_4(a, dummy);
-}
-
-template <class DST, class SRC>
-inline void interpolate_pixel_unaligned_2(DST *dest, const SRC *src,
- quint16 alpha)
-{
- const quint16 a = eff_alpha_2(alpha, dest);
- const quint16 ia = eff_ialpha_2(alpha, dest);
- dest[0] = DST(src[0]).byte_mul(a >> 8) + dest[0].byte_mul(ia >> 8);
- dest[1] = DST(src[1]).byte_mul(a & 0xff) + dest[1].byte_mul(ia & 0xff);
-}
-
-template <class DST, class SRC>
-inline void interpolate_pixel_2(DST *dest, const SRC *src, quint16 alpha)
-{
- Q_ASSERT((quintptr(dest) & 0x3) == 0);
- Q_ASSERT((quintptr(src) & 0x3) == 0);
-
- const quint16 a = eff_alpha_2(alpha, dest);
- const quint16 ia = eff_ialpha_2(alpha, dest);
-
- dest[0] = DST(src[0]).byte_mul(a >> 8) + dest[0].byte_mul(ia >> 8);
- dest[1] = DST(src[1]).byte_mul(a & 0xff) + dest[1].byte_mul(ia & 0xff);
-}
-
-template <class DST, class SRC>
-inline void interpolate_pixel(DST &dest, quint8 a, const SRC &src, quint8 b)
-{
- if (SRC::hasAlpha() && !DST::hasAlpha())
- interpolate_pixel(dest, a, DST(src), b);
- else
- dest = dest.byte_mul(a) + DST(src).byte_mul(b);
-}
-
-template <>
-inline void interpolate_pixel(qargb8565 &dest, quint8 a,
- const qargb8565 &src, quint8 b)
-{
- quint8 *d = reinterpret_cast<quint8*>(&dest);
- const quint8 *s = reinterpret_cast<const quint8*>(&src);
- d[0] = (d[0] * a + s[0] * b) >> 5;
-
- const quint16 x = (d[2] << 8) | d[1];
- const quint16 y = (s[2] << 8) | s[1];
- quint16 t = (((x & 0x07e0) * a + (y & 0x07e0) * b) >> 5) & 0x07e0;
- t |= (((x & 0xf81f) * a + (y & 0xf81f) * b) >> 5) & 0xf81f;
-
- d[1] = t & 0xff;
- d[2] = t >> 8;
-}
-
-template <>
-inline void interpolate_pixel(qrgb565 &dest, quint8 a,
- const qrgb565 &src, quint8 b)
-{
- const quint16 x = dest.rawValue();
- const quint16 y = src.rawValue();
- quint16 t = (((x & 0x07e0) * a + (y & 0x07e0) * b) >> 5) & 0x07e0;
- t |= (((x & 0xf81f) * a + (y & 0xf81f) * b) >> 5) & 0xf81f;
- dest = t;
-}
-
-template <>
-inline void interpolate_pixel(qrgb555 &dest, quint8 a,
- const qrgb555 &src, quint8 b)
-{
- const quint16 x = dest.rawValue();
- const quint16 y = src.rawValue();
- quint16 t = (((x & 0x03e0) * a + (y & 0x03e0) * b) >> 5) & 0x03e0;
- t |= ((((x & 0x7c1f) * a) + ((y & 0x7c1f) * b)) >> 5) & 0x7c1f;
- dest = t;
-}
-
-template <>
-inline void interpolate_pixel(qrgb444 &dest, quint8 a,
- const qrgb444 &src, quint8 b)
-{
- const quint16 x = dest.rawValue();
- const quint16 y = src.rawValue();
- quint16 t = ((x & 0x00f0) * a + (y & 0x00f0) * b) & 0x0f00;
- t |= ((x & 0x0f0f) * a + (y & 0x0f0f) * b) & 0xf0f0;
- quint16 *d = reinterpret_cast<quint16*>(&dest);
- *d = (t >> 4);
-}
-
-template <class DST, class SRC>
-inline void interpolate_pixel_2(DST *dest, quint8 a,
- const SRC *src, quint8 b)
-{
- Q_ASSERT((quintptr(dest) & 0x3) == 0);
- Q_ASSERT((quintptr(src) & 0x3) == 0);
-
- Q_ASSERT(!SRC::hasAlpha());
-
- dest[0] = dest[0].byte_mul(a) + DST(src[0]).byte_mul(b);
- dest[1] = dest[1].byte_mul(a) + DST(src[1]).byte_mul(b);
-}
-
-template <>
-inline void interpolate_pixel_2(qrgb565 *dest, quint8 a,
- const qrgb565 *src, quint8 b)
-{
- quint32 *x = reinterpret_cast<quint32*>(dest);
- const quint32 *y = reinterpret_cast<const quint32*>(src);
- quint32 t = (((*x & 0xf81f07e0) >> 5) * a +
- ((*y & 0xf81f07e0) >> 5) * b) & 0xf81f07e0;
- t |= (((*x & 0x07e0f81f) * a
- + (*y & 0x07e0f81f) * b) >> 5) & 0x07e0f81f;
- *x = t;
-}
-
-template <>
-inline void interpolate_pixel_2(qrgb555 *dest, quint8 a,
- const qrgb555 *src, quint8 b)
-{
- quint32 *x = reinterpret_cast<quint32*>(dest);
- const quint32 *y = reinterpret_cast<const quint32*>(src);
- quint32 t = (((*x & 0x7c1f03e0) >> 5) * a +
- ((*y & 0x7c1f03e0) >> 5) * b) & 0x7c1f03e0;
- t |= (((*x & 0x03e07c1f) * a
- + (*y & 0x03e07c1f) * b) >> 5) & 0x03e07c1f;
- *x = t;
-}
-
-template <>
-inline void interpolate_pixel_2(qrgb444 *dest, quint8 a,
- const qrgb444 *src, quint8 b)
-{
- quint32 *x = reinterpret_cast<quint32*>(dest);
- const quint32 *y = reinterpret_cast<const quint32*>(src);
- quint32 t = ((*x & 0x0f0f0f0f) * a + (*y & 0x0f0f0f0f) * b) & 0xf0f0f0f0;
- t |= ((*x & 0x00f000f0) * a + (*y & 0x00f000f0) * b) & 0x0f000f00;
- *x = t >> 4;
-}
-
-template <class DST, class SRC>
-inline void interpolate_pixel_4(DST *dest, const SRC *src, quint32 alpha)
-{
- Q_ASSERT((quintptr(dest) & 0x3) == 0);
- Q_ASSERT((quintptr(src) & 0x3) == 0);
-
- const quint32 a = eff_alpha_4(alpha, dest);
- const quint32 ia = eff_ialpha_4(alpha, dest);
- dest[0] = DST(src[0]).byte_mul(a >> 24)
- + dest[0].byte_mul(ia >> 24);
- dest[1] = DST(src[1]).byte_mul((a >> 16) & 0xff)
- + dest[1].byte_mul((ia >> 16) & 0xff);
- dest[2] = DST(src[2]).byte_mul((a >> 8) & 0xff)
- + dest[2].byte_mul((ia >> 8) & 0xff);
- dest[3] = DST(src[3]).byte_mul(a & 0xff)
- + dest[3].byte_mul(ia & 0xff);
-}
-
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
-template <>
-inline void interpolate_pixel_4(qargb8565 *dest, const qargb8565 *src,
- quint32 alpha)
-{
- Q_ASSERT((quintptr(dest) & 0x3) == 0);
- Q_ASSERT((quintptr(src) & 0x3) == 0);
-
- const quint32 a = eff_alpha_4(alpha, dest);
- const quint32 ia = eff_ialpha_4(alpha, dest);
- const quint32 *src32 = reinterpret_cast<const quint32*>(src);
- quint32 *dest32 = reinterpret_cast<quint32*>(dest);
-
- quint32 x, y, t;
- quint8 a8, ia8;
- {
- x = src32[0];
- y = dest32[0];
-
- a8 = a >> 24;
- ia8 = ia >> 24;
-
- // a0,g0
- t = (((x & 0x0007e0ff) * a8 + (y & 0x0007e0ff) * ia8) >> 5)
- & 0x0007e0ff;
-
- // r0,b0
- t |= (((x & 0x00f81f00) * a8 + (y & 0x00f81f00) * ia8) >> 5)
- & 0x00f81f00;
-
- a8 = (a >> 16) & 0xff;
- ia8 = (ia >> 16) & 0xff;
-
- // a1
- t |= (((x & 0xff000000) >> 5) * a8 + ((y & 0xff000000) >> 5) * ia8)
- & 0xff000000;
-
- dest32[0] = t;
- }
- {
- x = src32[1];
- y = dest32[1];
-
- // r1,b1
- t = (((x & 0x0000f81f) * a8 + (y & 0x0000f81f) * ia8) >> 5)
- & 0x0000f81f;
-
- // g1
- t |= (((x & 0x000007e0) * a8 + (y & 0x000007e0) * ia8) >> 5)
- & 0x000007e0;
-
- a8 = (a >> 8) & 0xff;
- ia8 = (ia >> 8) & 0xff;
-
- // a2
- t |= (((x & 0x00ff0000) * a8 + (y & 0x00ff0000) * ia8) >> 5)
- & 0x00ff0000;
-
- {
- // rgb2
- quint16 x16 = (x >> 24) | ((src32[2] & 0x000000ff) << 8);
- quint16 y16 = (y >> 24) | ((dest32[2] & 0x000000ff) << 8);
- quint16 t16;
-
- t16 = (((x16 & 0xf81f) * a8 + (y16 & 0xf81f) * ia8) >> 5) & 0xf81f;
- t16 |= (((x16 & 0x07e0) * a8 + (y16 & 0x07e0) * ia8) >> 5) & 0x07e0;
-
- // rg2
- t |= ((t16 & 0x00ff) << 24);
-
- dest32[1] = t;
-
- x = src32[2];
- y = dest32[2];
-
- // gb2
- t = (t16 >> 8);
- }
- }
- {
- a8 = a & 0xff;
- ia8 = ia & 0xff;
-
- // g3,a3
- t |= (((x & 0x07e0ff00) * a8 + (y & 0x07e0ff00) * ia8) >> 5)
- & 0x07e0ff00;
-
- // r3,b3
- t |= (((x & 0xf81f0000) >> 5) * a8 + ((y & 0xf81f0000) >> 5) * ia8)
- & 0xf81f0000;
-
- dest32[2] = t;
- }
-}
-#endif
-
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
-template <>
-inline void interpolate_pixel_4(qargb8555 *dest, const qargb8555 *src,
- quint32 alpha)
-{
- Q_ASSERT((quintptr(dest) & 0x3) == 0);
- Q_ASSERT((quintptr(src) & 0x3) == 0);
-
-
- const quint32 a = eff_alpha_4(alpha, dest);
- const quint32 ia = eff_ialpha_4(alpha, dest);
- const quint32 *src32 = reinterpret_cast<const quint32*>(src);
- quint32 *dest32 = reinterpret_cast<quint32*>(dest);
-
- quint32 x, y, t;
- quint8 a8, ia8;
- {
- x = src32[0];
- y = dest32[0];
-
- a8 = a >> 24;
- ia8 = ia >> 24;
-
- // a0,g0
- t = (((x & 0x0003e0ff) * a8 + (y & 0x0003e0ff) * ia8) >> 5)
- & 0x0003e0ff;
-
- // r0,b0
- t |= (((x & 0x007c1f00) * a8 + (y & 0x007c1f00) * ia8) >> 5)
- & 0x007c1f00;
-
- a8 = (a >> 16) & 0xff;
- ia8 = (ia >> 16) & 0xff;
-
- // a1
- t |= (((x & 0xff000000) >> 5) * a8 + ((y & 0xff000000) >> 5) * ia8)
- & 0xff000000;
-
- dest32[0] = t;
- }
- {
- x = src32[1];
- y = dest32[1];
-
- // r1,b1
- t = (((x & 0x00007c1f) * a8 + (y & 0x00007c1f) * ia8) >> 5)
- & 0x00007c1f;
-
- // g1
- t |= (((x & 0x000003e0) * a8 + (y & 0x000003e0) * ia8) >> 5)
- & 0x000003e0;
-
- a8 = (a >> 8) & 0xff;
- ia8 = (ia >> 8) & 0xff;
-
- // a2
- t |= (((x & 0x00ff0000) * a8 + (y & 0x00ff0000) * ia8) >> 5)
- & 0x00ff0000;
-
- {
- // rgb2
- quint16 x16 = (x >> 24) | ((src32[2] & 0x000000ff) << 8);
- quint16 y16 = (y >> 24) | ((dest32[2] & 0x000000ff) << 8);
- quint16 t16;
-
- t16 = (((x16 & 0x7c1f) * a8 + (y16 & 0x7c1f) * ia8) >> 5) & 0x7c1f;
- t16 |= (((x16 & 0x03e0) * a8 + (y16 & 0x03e0) * ia8) >> 5) & 0x03e0;
-
- // rg2
- t |= ((t16 & 0x00ff) << 24);
-
- dest32[1] = t;
-
- x = src32[2];
- y = dest32[2];
-
- // gb2
- t = (t16 >> 8);
- }
- }
- {
- a8 = a & 0xff;
- ia8 = ia & 0xff;
-
- // g3,a3
- t |= (((x & 0x03e0ff00) * a8 + (y & 0x03e0ff00) * ia8) >> 5)
- & 0x03e0ff00;
-
- // r3,b3
- t |= (((x & 0x7c1f0000) >> 5) * a8 + ((y & 0x7c1f0000) >> 5) * ia8)
- & 0x7c1f0000;
-
- dest32[2] = t;
- }
-}
-#endif
-
-template <>
-inline void interpolate_pixel_4(qrgb888 *dest, const qrgb888 *src,
- quint32 alpha)
-{
- Q_ASSERT((quintptr(dest) & 0x3) == 0);
- Q_ASSERT((quintptr(src) & 0x3) == 0);
-
- const quint32 a = eff_alpha_4(alpha, dest);
- const quint32 ia = eff_ialpha_4(alpha, dest);
- const quint32 *src32 = reinterpret_cast<const quint32*>(src);
- quint32 *dest32 = reinterpret_cast<quint32*>(dest);
-
- {
- quint32 x = src32[0];
- quint32 y = dest32[0];
-
- quint32 t;
- t = ((x >> 8) & 0xff00ff) * (a >> 24)
- + ((y >> 8) & 0xff00ff) * (ia >> 24);
- t = (t + ((t >> 8) & 0xff00ff) + 0x800080);
- t &= 0xff00ff00;
-
- x = (x & 0xff0000) * (a >> 24)
- + (x & 0x0000ff) * ((a >> 16) & 0xff)
- + (y & 0xff0000) * (ia >> 24)
- + (y & 0x0000ff) * ((ia >> 16) & 0xff);
- x = (x + ((x >> 8) & 0xff00ff) + 0x800080) >> 8;
- x &= 0x00ff00ff;
-
- dest32[0] = x | t;
- }
- {
- quint32 x = src32[1];
- quint32 y = dest32[1];
-
- quint32 t;
- t = ((x >> 8) & 0xff0000) * ((a >> 16) & 0xff)
- + ((x >> 8) & 0x0000ff) * ((a >> 8) & 0xff)
- + ((y >> 8) & 0xff0000) * ((ia >> 16) & 0xff)
- + ((y >> 8) & 0x0000ff) * ((ia >> 8) & 0xff);
- t = (t + ((t >> 8) & 0xff00ff) + 0x800080);
- t &= 0xff00ff00;
-
- x = (x & 0xff0000) * ((a >> 16) & 0xff)
- + (x & 0x0000ff) * ((a >> 8) & 0xff)
- + (y & 0xff0000) * ((ia >> 16) & 0xff)
- + (y & 0x0000ff) * ((ia >> 8) & 0xff);
- x = (x + ((x >> 8) & 0xff00ff) + 0x800080) >> 8;
- x &= 0x00ff00ff;
-
- dest32[1] = x | t;
- }
- {
- quint32 x = src32[2];
- quint32 y = dest32[2];
-
- quint32 t;
- t = ((x >> 8) & 0xff0000) * ((a >> 8) & 0xff)
- + ((x >> 8) & 0x0000ff) * (a & 0xff)
- + ((y >> 8) & 0xff0000) * ((ia >> 8) & 0xff)
- + ((y >> 8) & 0x0000ff) * (ia & 0xff);
- t = (t + ((t >> 8) & 0xff00ff) + 0x800080);
- t &= 0xff00ff00;
-
- x = (x & 0xff00ff) * (a & 0xff)
- + (y & 0xff00ff) * (ia & 0xff);
- x = (x + ((x >> 8) & 0xff00ff) + 0x800080) >> 8;
- x &= 0x00ff00ff;
-
- dest32[2] = x | t;
- }
-}
-
-template <class DST, class SRC>
-inline void interpolate_pixel_4(DST *dest, quint8 a,
- const SRC *src, quint8 b)
-{
- Q_ASSERT((quintptr(dest) & 0x3) == 0);
- Q_ASSERT((quintptr(src) & 0x3) == 0);
-
- dest[0] = dest[0].byte_mul(a) + DST(src[0]).byte_mul(b);
- dest[1] = dest[1].byte_mul(a) + DST(src[1]).byte_mul(b);
- dest[2] = dest[2].byte_mul(a) + DST(src[2]).byte_mul(b);
- dest[3] = dest[3].byte_mul(a) + DST(src[3]).byte_mul(b);
-}
-
-template <class DST, class SRC>
-inline void blend_sourceOver_4(DST *dest, const SRC *src)
-{
- Q_ASSERT((quintptr(dest) & 0x3) == 0);
- Q_ASSERT((quintptr(src) & 0x3) == 0);
-
- const quint32 a = alpha_4(src);
- if (a == 0xffffffff) {
- qt_memconvert(dest, src, 4);
- } else if (a > 0) {
- quint32 buf[3]; // array of quint32 to get correct alignment
- qt_memconvert((DST*)(void*)buf, src, 4);
- madd_4(dest, eff_ialpha_4(a, dest), (DST*)(void*)buf);
- }
-}
-
-template <>
-inline void blend_sourceOver_4(qargb8565 *dest, const qargb8565 *src)
-{
- Q_ASSERT((quintptr(dest) & 0x3) == 0);
- Q_ASSERT((quintptr(src) & 0x3) == 0);
-
- const quint32 a = alpha_4(src);
- if (a == 0xffffffff) {
- qt_memconvert(dest, src, 4);
- } else if (a > 0) {
- madd_4(dest, eff_ialpha_4(a, dest), src);
- }
-}
-
-template <>
-inline void blend_sourceOver_4(qargb8555 *dest, const qargb8555 *src)
-{
- Q_ASSERT((quintptr(dest) & 0x3) == 0);
- Q_ASSERT((quintptr(src) & 0x3) == 0);
-
- const quint32 a = alpha_4(src);
- if (a == 0xffffffff) {
- qt_memconvert(dest, src, 4);
- } else if (a > 0) {
- madd_4(dest, eff_ialpha_4(a, dest), src);
- }
-}
-
-template <>
-inline void blend_sourceOver_4(qargb6666 *dest, const qargb6666 *src)
-{
- Q_ASSERT((quintptr(dest) & 0x3) == 0);
- Q_ASSERT((quintptr(src) & 0x3) == 0);
-
- const quint32 a = alpha_4(src);
- if (a == 0xffffffff) {
- qt_memconvert(dest, src, 4);
- } else if (a > 0) {
- madd_4(dest, eff_ialpha_4(a, dest), src);
- }
-}
-
-template <class DST, class SRC>
-void QT_FASTCALL blendUntransformed_unaligned(DST *dest, const SRC *src,
- quint8 coverage, int length)
-{
- Q_ASSERT(coverage > 0);
-
- if (coverage < 255) {
- if (SRC::hasAlpha()) {
- for (int i = 0; i < length; ++i) {
- if (src[i].alpha()) {
- const quint8 alpha = qt_div_255(int(src[i].alpha()) * int(coverage));
- interpolate_pixel(dest[i], DST::ialpha(alpha),
- src[i], DST::alpha(alpha));
- }
- }
- } else {
- const quint8 alpha = DST::alpha(coverage);
- const quint8 ialpha = DST::ialpha(coverage);
- if (alpha) {
- for (int i = 0; i < length; ++i)
- interpolate_pixel(dest[i], ialpha, src[i], alpha);
- }
- }
- return;
- }
-
- Q_ASSERT(coverage == 0xff);
- Q_ASSERT(SRC::hasAlpha());
-
- if (SRC::hasAlpha()) {
- for (int i = 0; i < length; ++i) {
- const quint8 a = src->alpha();
- if (a == 0xff)
- *dest = DST(*src);
- else if (a > 0) {
- if (DST::hasAlpha())
- *dest = DST(*src).truncedAlpha() + dest->byte_mul(DST::ialpha(a));
- else
- *dest = DST(SRC(*src).truncedAlpha()) + dest->byte_mul(DST::ialpha(a));
- }
- ++src;
- ++dest;
- }
- }
-}
-
-template <class DST, class SRC>
-void QT_FASTCALL blendUntransformed_dest16(DST *dest, const SRC *src,
- quint8 coverage, int length)
-{
- Q_ASSERT(sizeof(DST) == 2);
- Q_ASSERT(sizeof(SRC) == 2);
- Q_ASSERT((quintptr(dest) & 0x3) == (quintptr(src) & 0x3));
- Q_ASSERT(coverage > 0);
-
- const int align = quintptr(dest) & 0x3;
-
- if (coverage < 255) {
- // align
- if (align) {
- const quint8 alpha = SRC::hasAlpha()
- ? qt_div_255(int(src->alpha()) * int(coverage))
- : coverage;
- if (alpha) {
- interpolate_pixel(*dest, DST::ialpha(alpha),
- *src, DST::alpha(alpha));
- }
- ++dest;
- ++src;
- --length;
- }
-
- if (SRC::hasAlpha()) {
- while (length >= 2) {
- const quint16 alpha16 = BYTE_MUL(uint(alpha_2(src)), uint(coverage));
- interpolate_pixel_2(dest, src, alpha16);
- length -= 2;
- src += 2;
- dest += 2;
- }
- } else {
- const quint8 alpha = DST::alpha(coverage);
- const quint8 ialpha = DST::ialpha(coverage);
-
- while (length >= 2) {
- interpolate_pixel_2(dest, ialpha, src, alpha);
- length -= 2;
- src += 2;
- dest += 2;
- }
- }
-
- // tail
- if (length) {
- const quint8 alpha = SRC::hasAlpha()
- ? qt_div_255(int(src->alpha()) * int(coverage))
- : coverage;
- if (alpha) {
- interpolate_pixel(*dest, DST::ialpha(alpha),
- *src, DST::alpha(alpha));
- }
- }
-
- return;
- }
-
- Q_ASSERT(SRC::hasAlpha());
- if (SRC::hasAlpha()) {
- if (align) {
- const quint8 alpha = src->alpha();
- if (alpha == 0xff)
- *dest = DST(*src);
- else if (alpha > 0)
- *dest = DST(*src).truncedAlpha() + dest->byte_mul(DST::ialpha(alpha));
- ++dest;
- ++src;
- --length;
- }
-
- while (length >= 2) {
- Q_ASSERT((quintptr(dest) & 3) == 0);
- Q_ASSERT((quintptr(src) & 3) == 0);
-
- const quint16 a = alpha_2(src);
- if (a == 0xffff) {
- qt_memconvert(dest, src, 2);
- } else if (a > 0) {
- quint32 buf;
- if (sizeof(DST) == 2)
- qt_memconvert((DST*)(void*)&buf, src, 2);
- madd_2(dest, eff_ialpha_2(a, dest), (DST*)(void*)&buf);
- }
-
- length -= 2;
- src += 2;
- dest += 2;
- }
-
- if (length) {
- const quint8 alpha = src->alpha();
- if (alpha == 0xff)
- *dest = DST(*src);
- else if (alpha > 0)
- *dest = DST(*src).truncedAlpha() + dest->byte_mul(DST::ialpha(alpha));
- }
- }
-}
-
-template <class DST, class SRC>
-void QT_FASTCALL blendUntransformed_dest24(DST *dest, const SRC *src,
- quint8 coverage, int length)
-{
- Q_ASSERT((quintptr(dest) & 0x3) == (quintptr(src) & 0x3));
- Q_ASSERT(sizeof(DST) == 3);
- Q_ASSERT(coverage > 0);
-
- const int align = quintptr(dest) & 0x3;
-
- if (coverage < 255) {
- // align
- for (int i = 0; i < align; ++i) {
- if (SRC::hasAlpha()) {
- const quint8 alpha = qt_div_255(int(src->alpha()) * int(coverage));
- if (alpha)
- interpolate_pixel(*dest, DST::ialpha(alpha),
- *src, DST::alpha(alpha));
- } else {
- interpolate_pixel(*dest, DST::ialpha(coverage),
- *src, DST::alpha(coverage));
- }
- ++dest;
- ++src;
- --length;
- }
-
- if (SRC::hasAlpha()) {
- while (length >= 4) {
- const quint32 alpha = QT_PREPEND_NAMESPACE(BYTE_MUL)(uint(alpha_4(src)), uint(coverage));
- if (alpha)
- interpolate_pixel_4(dest, src, alpha);
- length -= 4;
- src += 4;
- dest += 4;
- }
- } else {
- const quint8 alpha = DST::alpha(coverage);
- const quint8 ialpha = DST::ialpha(coverage);
- while (length >= 4) {
- interpolate_pixel_4(dest, ialpha, src, alpha);
- length -= 4;
- src += 4;
- dest += 4;
- }
- }
-
- // tail
- while (length--) {
- if (SRC::hasAlpha()) {
- const quint8 alpha = qt_div_255(int(src->alpha()) * int(coverage));
- if (alpha)
- interpolate_pixel(*dest, DST::ialpha(alpha),
- *src, DST::alpha(alpha));
- } else {
- interpolate_pixel(*dest, DST::ialpha(coverage),
- *src, DST::alpha(coverage));
- }
- ++dest;
- ++src;
- }
-
- return;
- }
-
-
- Q_ASSERT(coverage == 255);
- Q_ASSERT(SRC::hasAlpha());
-
- if (SRC::hasAlpha()) {
- // align
- for (int i = 0; i < align; ++i) {
- const quint8 a = src->alpha();
- if (a == 0xff) {
- *dest = DST(*src);
- } else if (a > 0) {
- *dest = DST(*src).truncedAlpha() + dest->byte_mul(DST::ialpha(a));
- }
- ++dest;
- ++src;
- --length;
- }
-
- while (length >= 4) {
- blend_sourceOver_4(dest, src);
- length -= 4;
- src += 4;
- dest += 4;
- }
-
- // tail
- while (length--) {
- const quint8 a = src->alpha();
- if (a == 0xff) {
- *dest = DST(*src);
- } else if (a > 0) {
- *dest = DST(*src).truncedAlpha() + dest->byte_mul(DST::ialpha(a));
- }
- ++dest;
- ++src;
- }
- }
-}
-
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-void QT_FASTCALL blendUntransformed(int count, const QSpan *spans, void *userData)
+static void blend_untransformed_rgb565(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData*>(userData);
QPainter::CompositionMode mode = data->rasterBuffer->compositionMode;
- if (mode != QPainter::CompositionMode_SourceOver &&
- mode != QPainter::CompositionMode_Source)
+ if (data->texture.format != QImage::Format_RGB16
+ || (mode != QPainter::CompositionMode_SourceOver
+ && mode != QPainter::CompositionMode_Source))
{
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_untransformed_generic(count, spans, userData);
return;
}
- const bool modeSource = !SRC::hasAlpha() ||
- mode == QPainter::CompositionMode_Source;
const int image_width = data->texture.width;
const int image_height = data->texture.height;
int xoff = -qRound(-data->dx);
@@ -4917,20 +4128,15 @@ void QT_FASTCALL blendUntransformed(int count, const QSpan *spans, void *userDat
if (sx + length > image_width)
length = image_width - sx;
if (length > 0) {
- DST *dest = ((DST*)data->rasterBuffer->scanLine(spans->y)) + x;
- const SRC *src = (SRC*)data->texture.scanLine(sy) + sx;
- if (modeSource && coverage == 255) {
- qt_memconvert<DST, SRC>(dest, src, length);
- } else if (sizeof(DST) == 3 && sizeof(SRC) == 3 && length >= 3 &&
- (quintptr(dest) & 3) == (quintptr(src) & 3))
- {
- blendUntransformed_dest24(dest, src, coverage, length);
- } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && length >= 3 &&
- (quintptr(dest) & 3) == (quintptr(src) & 3))
- {
- blendUntransformed_dest16(dest, src, coverage, length);
+ quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + x;
+ const quint16 *src = (quint16 *)data->texture.scanLine(sy) + sx;
+ if (coverage == 255) {
+ memcpy(dest, src, length * sizeof(quint16));
} else {
- blendUntransformed_unaligned(dest, src, coverage, length);
+ const quint8 alpha = (coverage + 1) >> 3;
+ const quint8 ialpha = 0x20 - alpha;
+ if (alpha > 0)
+ blend_sourceOver_rgb16_rgb16(dest, src, length, alpha, ialpha);
}
}
}
@@ -4938,69 +4144,7 @@ void QT_FASTCALL blendUntransformed(int count, const QSpan *spans, void *userDat
}
}
-static void blend_untransformed_rgb888(int count, const QSpan *spans,
- void *userData)
-{
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_untransformed_argb6666(int count, const QSpan *spans,
- void *userData)
-{
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_untransformed_rgb666(int count, const QSpan *spans,
- void *userData)
-{
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_untransformed_argb8565(int count, const QSpan *spans,
- void *userData)
-{
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_untransformed_rgb565(int count, const QSpan *spans,
- void *userData)
-{
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
- blendUntransformed<qrgb565, qargb8565>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB16)
- blendUntransformed<qrgb565, qrgb565>(count, spans, userData);
- else
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_untransformed_argb8555(int count, const QSpan *spans,
- void *userData)
-{
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_untransformed_rgb555(int count, const QSpan *spans,
- void *userData)
-{
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_untransformed_argb4444(int count, const QSpan *spans,
- void *userData)
-{
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_untransformed_rgb444(int count, const QSpan *spans,
- void *userData)
-{
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
-}
-
-template <SpanMethod spanMethod>
-Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_generic(int count, const QSpan *spans, void *userData)
+static void blend_tiled_generic(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
@@ -5034,15 +4178,10 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_generic(int count, const QSpan *span
if (buffer_size < l)
l = buffer_size;
const uint *src = op.src_fetch(src_buffer, &op, data, sy, sx, l);
- if (spanMethod == RegularSpans) {
- uint *dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
- op.func(dest, src, l, coverage);
- if (op.dest_store)
- op.dest_store(data->rasterBuffer, x, spans->y, dest, l);
- } else {
- drawBufferSpan(data, src, l, x, spans->y, l,
- coverage);
- }
+ uint *dest = op.dest_fetch ? op.dest_fetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
+ op.func(dest, src, l, coverage);
+ if (op.dest_store)
+ op.dest_store(data->rasterBuffer, x, spans->y, dest, l);
x += l;
sx += l;
length -= l;
@@ -5053,13 +4192,12 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_generic(int count, const QSpan *span
}
}
-template <SpanMethod spanMethod>
-Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_argb(int count, const QSpan *spans, void *userData)
+static void blend_tiled_argb(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format != QImage::Format_ARGB32_Premultiplied
&& data->texture.format != QImage::Format_RGB32) {
- blend_tiled_generic<spanMethod>(count, spans, userData);
+ blend_tiled_generic(count, spans, userData);
return;
}
@@ -5091,13 +4229,8 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_argb(int count, const QSpan *spans,
if (buffer_size < l)
l = buffer_size;
const uint *src = (uint *)data->texture.scanLine(sy) + sx;
- if (spanMethod == RegularSpans) {
- uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x;
- op.func(dest, src, l, coverage);
- } else {
- drawBufferSpan(data, src, buffer_size,
- x, spans->y, l, coverage);
- }
+ uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x;
+ op.func(dest, src, l, coverage);
x += l;
length -= l;
sx = 0;
@@ -5106,21 +4239,19 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_tiled_argb(int count, const QSpan *spans,
}
}
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION void blendTiled(int count, const QSpan *spans, void *userData)
+static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData*>(userData);
QPainter::CompositionMode mode = data->rasterBuffer->compositionMode;
- if (mode != QPainter::CompositionMode_SourceOver &&
- mode != QPainter::CompositionMode_Source)
+ if (data->texture.format != QImage::Format_RGB16
+ || (mode != QPainter::CompositionMode_SourceOver
+ && mode != QPainter::CompositionMode_Source))
{
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_tiled_generic(count, spans, userData);
return;
}
- const bool modeSource = !SRC::hasAlpha() ||
- mode == QPainter::CompositionMode_Source;
const int image_width = data->texture.width;
const int image_height = data->texture.height;
int xoff = -qRound(-data->dx) % image_width;
@@ -5147,7 +4278,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTiled(int count, const QSpan *spans, void *
if (sy < 0)
sy += image_height;
- if (modeSource && coverage == 255) {
+ if (coverage == 255) {
// Copy the first texture block
length = qMin(image_width,length);
int tx = x;
@@ -5155,10 +4286,9 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTiled(int count, const QSpan *spans, void *
int l = qMin(image_width - sx, length);
if (buffer_size < l)
l = buffer_size;
- DST *dest = ((DST*)data->rasterBuffer->scanLine(spans->y)) + tx;
- const SRC *src = (SRC*)data->texture.scanLine(sy) + sx;
-
- qt_memconvert<DST, SRC>(dest, src, l);
+ quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans->y)) + tx;
+ const quint16 *src = (quint16 *)data->texture.scanLine(sy) + sx;
+ memcpy(dest, src, l * sizeof(quint16));
length -= l;
tx += l;
sx = 0;
@@ -5172,110 +4302,51 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTiled(int count, const QSpan *spans, void *
// - can use memcpy
int copy_image_width = qMin(image_width, int(spans->len));
length = spans->len - copy_image_width;
- DST *src = ((DST*)data->rasterBuffer->scanLine(spans->y)) + x;
- DST *dest = src + copy_image_width;
+ quint16 *src = ((quint16 *)data->rasterBuffer->scanLine(spans->y)) + x;
+ quint16 *dest = src + copy_image_width;
while (copy_image_width < length) {
- qt_memconvert(dest, src, copy_image_width);
+ memcpy(dest, src, copy_image_width * sizeof(quint16));
dest += copy_image_width;
length -= copy_image_width;
copy_image_width *= 2;
}
if (length > 0)
- qt_memconvert(dest, src, length);
+ memcpy(dest, src, length * sizeof(quint16));
} else {
- while (length) {
- int l = qMin(image_width - sx, length);
- if (buffer_size < l)
- l = buffer_size;
- DST *dest = ((DST*)data->rasterBuffer->scanLine(spans->y)) + x;
- const SRC *src = (SRC*)data->texture.scanLine(sy) + sx;
- if (sizeof(DST) == 3 && sizeof(SRC) == 3 && l >= 4 &&
- (quintptr(dest) & 3) == (quintptr(src) & 3))
- {
- blendUntransformed_dest24(dest, src, coverage, l);
- } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 &&
- (quintptr(dest) & 3) == (quintptr(src) & 3))
- {
- blendUntransformed_dest16(dest, src, coverage, l);
- } else {
- blendUntransformed_unaligned(dest, src, coverage, l);
+ const quint8 alpha = (coverage + 1) >> 3;
+ const quint8 ialpha = 0x20 - alpha;
+ if (alpha > 0) {
+ while (length) {
+ int l = qMin(image_width - sx, length);
+ if (buffer_size < l)
+ l = buffer_size;
+ quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans->y)) + x;
+ const quint16 *src = (quint16 *)data->texture.scanLine(sy) + sx;
+ blend_sourceOver_rgb16_rgb16(dest, src, l, alpha, ialpha);
+ x += l;
+ length -= l;
+ sx = 0;
}
-
- x += l;
- length -= l;
- sx = 0;
}
}
++spans;
}
}
-static void blend_tiled_rgb888(int count, const QSpan *spans, void *userData)
-{
- blend_tiled_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_tiled_argb6666(int count, const QSpan *spans, void *userData)
-{
- blend_tiled_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_tiled_rgb666(int count, const QSpan *spans, void *userData)
-{
- blend_tiled_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_tiled_argb8565(int count, const QSpan *spans, void *userData)
-{
- blend_tiled_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData)
-{
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
- blendTiled<qrgb565, qargb8565>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB16)
- blendTiled<qrgb565, qrgb565>(count, spans, userData);
- else
- blend_tiled_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_tiled_argb8555(int count, const QSpan *spans, void *userData)
-{
- blend_tiled_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_tiled_rgb555(int count, const QSpan *spans, void *userData)
-{
- blend_tiled_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_tiled_argb4444(int count, const QSpan *spans, void *userData)
-{
- blend_tiled_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_tiled_rgb444(int count, const QSpan *spans, void *userData)
-{
- blend_tiled_generic<RegularSpans>(count, spans, userData);
-}
-
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan *spans,
- void *userData)
+static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData*>(userData);
QPainter::CompositionMode mode = data->rasterBuffer->compositionMode;
-
- if (mode != QPainter::CompositionMode_SourceOver) {
- blend_src_generic<RegularSpans>(count, spans, userData);
+ if (data->texture.format != QImage::Format_RGB16
+ || (mode != QPainter::CompositionMode_SourceOver
+ && mode != QPainter::CompositionMode_Source))
+ {
+ blend_src_generic(count, spans, userData);
return;
}
- SRC buffer[buffer_size];
+ quint16 buffer[buffer_size];
const int src_minx = data->texture.x1;
const int src_miny = data->texture.y1;
@@ -5289,13 +4360,14 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan
while (count--) {
const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8;
- if (coverage == 0) {
+ const quint8 alpha = (coverage + 1) >> 3;
+ const quint8 ialpha = 0x20 - alpha;
+ if (alpha == 0) {
++spans;
continue;
}
- DST *dest = (DST*)data->rasterBuffer->scanLine(spans->y)
- + spans->x;
+ quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x;
const qreal cx = spans->x + qreal(0.5);
const qreal cy = spans->y + qreal(0.5);
int x = int((data->m21 * cy
@@ -5305,84 +4377,58 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan
int length = spans->len;
while (length) {
- const int l = qMin(length, buffer_size);
+ int l;
+ quint16 *b;
+ if (ialpha == 0) {
+ l = length;
+ b = dest;
+ } else {
+ l = qMin(length, buffer_size);
+ b = buffer;
+ }
+ const quint16 *end = b + l;
- const SRC *end = buffer + l;
- SRC *b = buffer;
while (b < end) {
int x1 = (x >> 16);
int x2;
int y1 = (y >> 16);
int y2;
- const int distx = (x & 0x0000ffff) >> 8;
- const int disty = (y & 0x0000ffff) >> 8;
+ fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_minx, src_maxx, x1, x2);
+ fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_miny, src_maxy, y1, y2);
+
+ const quint16 *src1 = (quint16*)data->texture.scanLine(y1);
+ const quint16 *src2 = (quint16*)data->texture.scanLine(y2);
+ quint16 tl = src1[x1];
+ const quint16 tr = src1[x2];
+ quint16 bl = src2[x1];
+ const quint16 br = src2[x2];
+
+ const uint distxsl8 = x & 0xff00;
+ const uint distysl8 = y & 0xff00;
+ const uint distx = distxsl8 >> 8;
+ const uint disty = distysl8 >> 8;
+ const uint distxy = distx * disty;
+
+ const uint tlw = 0x10000 - distxsl8 - distysl8 + distxy; // (256 - distx) * (256 - disty)
+ const uint trw = distxsl8 - distxy; // distx * (256 - disty)
+ const uint blw = distysl8 - distxy; // (256 - distx) * disty
+ const uint brw = distxy; // distx * disty
+ uint red = ((tl & 0xf800) * tlw + (tr & 0xf800) * trw
+ + (bl & 0xf800) * blw + (br & 0xf800) * brw) & 0xf8000000;
+ uint green = ((tl & 0x07e0) * tlw + (tr & 0x07e0) * trw
+ + (bl & 0x07e0) * blw + (br & 0x07e0) * brw) & 0x07e00000;
+ uint blue = ((tl & 0x001f) * tlw + (tr & 0x001f) * trw
+ + (bl & 0x001f) * blw + (br & 0x001f) * brw);
+ *b = quint16((red | green | blue) >> 16);
- if (x1 < src_minx) {
- x2 = x1 = src_minx;
- } else if (x1 >= src_maxx) {
- x2 = x1 = src_maxx;
- } else {
- x2 = x1 + 1;
- }
- if (y1 < src_miny) {
- y2 = y1 = src_miny;
- } else if (y1 >= src_maxy) {
- y2 = y1 = src_maxy;
- } else {
- y2 = y1 + 1;
- }
-#if 0
- if (x1 == x2) {
- if (y1 == y2) {
- *b = ((SRC*)data->texture.scanLine(y1))[x1];
- } else {
- *b = ((SRC*)data->texture.scanLine(y1))[x1];
- const SRC t = data->texture.scanLine(y2)[x1];
- interpolate_pixel(*b, SRC::ialpha(disty),
- t, SRC::alpha(disty));
- }
- } else if (y1 == y2) {
- *b = ((SRC*)data->texture.scanLine(y1))[x1];
- const SRC t = ((SRC*)data->texture.scanLine(y1))[x2];
- interpolate_pixel(*b, SRC::ialpha(distx),
- t, SRC::alpha(distx));
- } else
-#endif
- {
- const SRC *src1 = (SRC*)data->texture.scanLine(y1);
- const SRC *src2 = (SRC*)data->texture.scanLine(y2);
- SRC tl = src1[x1];
- const SRC tr = src1[x2];
- SRC bl = src2[x1];
- const SRC br = src2[x2];
- const quint8 ax = SRC::alpha(distx);
- const quint8 iax = SRC::ialpha(distx);
-
- interpolate_pixel(tl, iax, tr, ax);
- interpolate_pixel(bl, iax, br, ax);
- interpolate_pixel(tl, SRC::ialpha(disty),
- bl, SRC::alpha(disty));
- *b = tl;
- }
++b;
-
x += fdx;
y += fdy;
}
- if (!SRC::hasAlpha() && coverage == 255) {
- qt_memconvert(dest, buffer, l);
- } else if (sizeof(DST) == 3 && l >= 4 &&
- (quintptr(dest) & 3) == (quintptr(buffer) & 3))
- {
- blendUntransformed_dest24(dest, buffer, coverage, l);
- } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 &&
- (quintptr(dest) & 3) == (quintptr(buffer) & 3)) {
- blendUntransformed_dest16(dest, buffer, coverage, l);
- } else {
- blendUntransformed_unaligned(dest, buffer, coverage, l);
- }
+ if (ialpha != 0)
+ blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha);
dest += l;
length -= l;
@@ -5396,13 +4442,14 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan
while (count--) {
const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8;
- if (coverage == 0) {
+ const quint8 alpha = (coverage + 1) >> 3;
+ const quint8 ialpha = 0x20 - alpha;
+ if (alpha == 0) {
++spans;
continue;
}
- DST *dest = (DST*)data->rasterBuffer->scanLine(spans->y)
- + spans->x;
+ quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x;
const qreal cx = spans->x + qreal(0.5);
const qreal cy = spans->y + qreal(0.5);
@@ -5413,9 +4460,17 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan
int length = spans->len;
while (length) {
- const int l = qMin(length, buffer_size);
- const SRC *end = buffer + l;
- SRC *b = buffer;
+ int l;
+ quint16 *b;
+ if (ialpha == 0) {
+ l = length;
+ b = dest;
+ } else {
+ l = qMin(length, buffer_size);
+ b = buffer;
+ }
+ const quint16 *end = b + l;
+
while (b < end) {
const qreal iw = w == 0 ? 1 : 1 / w;
const qreal px = x * iw - qreal(0.5);
@@ -5426,56 +4481,42 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan
int y1 = int(py) - (py < 0);
int y2;
- const int distx = int((px - x1) * 256);
- const int disty = int((py - y1) * 256);
+ fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_minx, src_maxx, x1, x2);
+ fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_miny, src_maxy, y1, y2);
+
+ const quint16 *src1 = (quint16 *)data->texture.scanLine(y1);
+ const quint16 *src2 = (quint16 *)data->texture.scanLine(y2);
+ quint16 tl = src1[x1];
+ const quint16 tr = src1[x2];
+ quint16 bl = src2[x1];
+ const quint16 br = src2[x2];
+
+ const uint distx = uint((px - x1) * 256);
+ const uint disty = uint((py - y1) * 256);
+ const uint distxsl8 = distx << 8;
+ const uint distysl8 = disty << 8;
+ const uint distxy = distx * disty;
+
+ const uint tlw = 0x10000 - distxsl8 - distysl8 + distxy; // (256 - distx) * (256 - disty)
+ const uint trw = distxsl8 - distxy; // distx * (256 - disty)
+ const uint blw = distysl8 - distxy; // (256 - distx) * disty
+ const uint brw = distxy; // distx * disty
+ uint red = ((tl & 0xf800) * tlw + (tr & 0xf800) * trw
+ + (bl & 0xf800) * blw + (br & 0xf800) * brw) & 0xf8000000;
+ uint green = ((tl & 0x07e0) * tlw + (tr & 0x07e0) * trw
+ + (bl & 0x07e0) * blw + (br & 0x07e0) * brw) & 0x07e00000;
+ uint blue = ((tl & 0x001f) * tlw + (tr & 0x001f) * trw
+ + (bl & 0x001f) * blw + (br & 0x001f) * brw);
+ *b = quint16((red | green | blue) >> 16);
- if (x1 < src_minx) {
- x2 = x1 = src_minx;
- } else if (x1 >= src_maxx) {
- x2 = x1 = src_maxx;
- } else {
- x2 = x1 + 1;
- }
- if (y1 < src_miny) {
- y2 = y1 = src_miny;
- } else if (y1 >= src_maxy) {
- y2 = y1 = src_maxy;
- } else {
- y2 = y1 + 1;
- }
-
- const SRC *src1 = (SRC*)data->texture.scanLine(y1);
- const SRC *src2 = (SRC*)data->texture.scanLine(y2);
- SRC tl = src1[x1];
- const SRC tr = src1[x2];
- SRC bl = src2[x1];
- const SRC br = src2[x2];
- const quint8 ax = SRC::alpha(distx);
- const quint8 iax = SRC::ialpha(distx);
-
- interpolate_pixel(tl, iax, tr, ax);
- interpolate_pixel(bl, iax, br, ax);
- interpolate_pixel(tl, SRC::ialpha(disty),
- bl, SRC::alpha(disty));
- *b = tl;
++b;
-
x += fdx;
y += fdy;
w += fdw;
}
- if (!SRC::hasAlpha() && coverage == 255) {
- qt_memconvert(dest, buffer, l);
- } else if (sizeof(DST) == 3 && l >= 4 &&
- (quintptr(dest) & 3) == (quintptr(buffer) & 3))
- {
- blendUntransformed_dest24(dest, buffer, coverage, l);
- } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 &&
- (quintptr(dest) & 3) == (quintptr(buffer) & 3)) {
- blendUntransformed_dest16(dest, buffer, coverage, l);
- } else {
- blendUntransformed_unaligned(dest, buffer, coverage, l);
- }
+
+ if (ialpha != 0)
+ blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha);
dest += l;
length -= l;
@@ -5485,66 +4526,12 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan
}
}
-static void blend_transformed_bilinear_rgb888(int count, const QSpan *spans, void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_bilinear_argb6666(int count, const QSpan *spans, void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_bilinear_rgb666(int count, const QSpan *spans, void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_bilinear_argb8565(int count, const QSpan *spans, void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans,
- void *userData)
-{
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_RGB16)
- blendTransformedBilinear<qrgb565, qrgb565>(count, spans, userData);
- else if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
- blendTransformedBilinear<qrgb565, qargb8565>(count, spans, userData);
- else
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_bilinear_argb8555(int count, const QSpan *spans, void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_bilinear_rgb555(int count, const QSpan *spans, void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_bilinear_argb4444(int count, const QSpan *spans, void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_bilinear_rgb444(int count, const QSpan *spans, void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-template <SpanMethod spanMethod>
-Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *spans, void *userData)
+static void blend_transformed_argb(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format != QImage::Format_ARGB32_Premultiplied
&& data->texture.format != QImage::Format_RGB32) {
- blend_src_generic<spanMethod>(count, spans, userData);
+ blend_src_generic(count, spans, userData);
return;
}
@@ -5553,7 +4540,6 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *s
int image_width = data->texture.width;
int image_height = data->texture.height;
- const int scanline_offset = data->texture.bytesPerLine / 4;
if (data->fast_matrix) {
// The increment pr x in the scanline
@@ -5564,7 +4550,6 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *s
void *t = data->rasterBuffer->scanLine(spans->y);
uint *target = ((uint *)t) + spans->x;
- uint *image_bits = (uint *)data->texture.imageData;
const qreal cx = spans->x + qreal(0.5);
const qreal cy = spans->y + qreal(0.5);
@@ -5581,24 +4566,15 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *s
const uint *end = buffer + l;
uint *b = buffer;
while (b < end) {
- int px = x >> 16;
- int py = y >> 16;
+ int px = qBound(0, x >> 16, image_width - 1);
+ int py = qBound(0, y >> 16, image_height - 1);
+ *b = reinterpret_cast<const uint *>(data->texture.scanLine(py))[px];
- bool out = (px < 0) || (px >= image_width)
- || (py < 0) || (py >= image_height);
-
- int y_offset = py * scanline_offset;
- *b = out ? uint(0) : image_bits[y_offset + px];
x += fdx;
y += fdy;
++b;
}
- if (spanMethod == RegularSpans)
- func(target, buffer, l, coverage);
- else
- drawBufferSpan(data, buffer, buffer_size,
- spans->x + spans->len - length,
- spans->y, l, coverage);
+ func(target, buffer, l, coverage);
target += l;
length -= l;
}
@@ -5612,7 +4588,6 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *s
void *t = data->rasterBuffer->scanLine(spans->y);
uint *target = ((uint *)t) + spans->x;
- uint *image_bits = (uint *)data->texture.imageData;
const qreal cx = spans->x + qreal(0.5);
const qreal cy = spans->y + qreal(0.5);
@@ -5631,26 +4606,17 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *s
const qreal iw = w == 0 ? 1 : 1 / w;
const qreal tx = x * iw;
const qreal ty = y * iw;
- const int px = int(tx) - (tx < 0);
- const int py = int(ty) - (ty < 0);
+ const int px = qBound(0, int(tx) - (tx < 0), image_width - 1);
+ const int py = qBound(0, int(ty) - (ty < 0), image_height - 1);
- bool out = (px < 0) || (px >= image_width)
- || (py < 0) || (py >= image_height);
-
- int y_offset = py * scanline_offset;
- *b = out ? uint(0) : image_bits[y_offset + px];
+ *b = reinterpret_cast<const uint *>(data->texture.scanLine(py))[px];
x += fdx;
y += fdy;
w += fdw;
++b;
}
- if (spanMethod == RegularSpans)
- func(target, buffer, l, coverage);
- else
- drawBufferSpan(data, buffer, buffer_size,
- spans->x + spans->len - length,
- spans->y, l, coverage);
+ func(target, buffer, l, coverage);
target += l;
length -= l;
}
@@ -5659,18 +4625,20 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *s
}
}
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans, void *userData)
+static void blend_transformed_rgb565(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData*>(userData);
QPainter::CompositionMode mode = data->rasterBuffer->compositionMode;
- if (mode != QPainter::CompositionMode_SourceOver) {
- blend_src_generic<RegularSpans>(count, spans, userData);
+ if (data->texture.format != QImage::Format_RGB16
+ || (mode != QPainter::CompositionMode_SourceOver
+ && mode != QPainter::CompositionMode_Source))
+ {
+ blend_src_generic(count, spans, userData);
return;
}
- SRC buffer[buffer_size];
+ quint16 buffer[buffer_size];
const int image_width = data->texture.width;
const int image_height = data->texture.height;
@@ -5681,13 +4649,14 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans,
while (count--) {
const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8;
- if (coverage == 0) {
+ const quint8 alpha = (coverage + 1) >> 3;
+ const quint8 ialpha = 0x20 - alpha;
+ if (alpha == 0) {
++spans;
continue;
}
- DST *dest = (DST*)data->rasterBuffer->scanLine(spans->y)
- + spans->x;
+ quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x;
const qreal cx = spans->x + qreal(0.5);
const qreal cy = spans->y + qreal(0.5);
int x = int((data->m21 * cy
@@ -5697,39 +4666,30 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans,
int length = spans->len;
while (length) {
- const int l = qMin(length, buffer_size);
+ int l;
+ quint16 *b;
+ if (ialpha == 0) {
+ l = length;
+ b = dest;
+ } else {
+ l = qMin(length, buffer_size);
+ b = buffer;
+ }
+ const quint16 *end = b + l;
- const SRC *end = buffer + l;
- SRC *b = buffer;
while (b < end) {
- const int px = (x >> 16);
- const int py = (y >> 16);
+ const int px = qBound(0, x >> 16, image_width - 1);
+ const int py = qBound(0, y >> 16, image_height - 1);
- if ((px < 0) || (px >= image_width) ||
- (py < 0) || (py >= image_height))
- {
- *b = 0;
- } else {
- *b = ((SRC*)data->texture.scanLine(py))[px];
- }
+ *b = ((quint16 *)data->texture.scanLine(py))[px];
++b;
x += fdx;
y += fdy;
}
- if (!SRC::hasAlpha() && coverage == 255) {
- qt_memconvert(dest, buffer, l);
- } else if (sizeof(DST) == 3 && sizeof(SRC) == 3 && l >= 4 &&
- (quintptr(dest) & 3) == (quintptr(buffer) & 3))
- {
- blendUntransformed_dest24(dest, buffer, coverage, l);
- } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 &&
- (quintptr(dest) & 3) == (quintptr(buffer) & 3)) {
- blendUntransformed_dest16(dest, buffer, coverage, l);
- } else {
- blendUntransformed_unaligned(dest, buffer, coverage, l);
- }
+ if (ialpha != 0)
+ blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha);
dest += l;
length -= l;
@@ -5743,13 +4703,14 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans,
while (count--) {
const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8;
- if (coverage == 0) {
+ const quint8 alpha = (coverage + 1) >> 3;
+ const quint8 ialpha = 0x20 - alpha;
+ if (alpha == 0) {
++spans;
continue;
}
- DST *dest = (DST*)data->rasterBuffer->scanLine(spans->y)
- + spans->x;
+ quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x;
const qreal cx = spans->x + qreal(0.5);
const qreal cy = spans->y + qreal(0.5);
@@ -5760,42 +4721,35 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans,
int length = spans->len;
while (length) {
- const int l = qMin(length, buffer_size);
- const SRC *end = buffer + l;
- SRC *b = buffer;
+ int l;
+ quint16 *b;
+ if (ialpha == 0) {
+ l = length;
+ b = dest;
+ } else {
+ l = qMin(length, buffer_size);
+ b = buffer;
+ }
+ const quint16 *end = b + l;
+
while (b < end) {
const qreal iw = w == 0 ? 1 : 1 / w;
const qreal tx = x * iw;
const qreal ty = y * iw;
- const int px = int(tx) - (tx < 0);
- const int py = int(ty) - (ty < 0);
+ const int px = qBound(0, int(tx) - (tx < 0), image_width - 1);
+ const int py = qBound(0, int(ty) - (ty < 0), image_height - 1);
- if ((px < 0) || (px >= image_width) ||
- (py < 0) || (py >= image_height))
- {
- *b = 0;
- } else {
- *b = ((SRC*)data->texture.scanLine(py))[px];
- }
+ *b = ((quint16 *)data->texture.scanLine(py))[px];
++b;
x += fdx;
y += fdy;
w += fdw;
}
- if (!SRC::hasAlpha() && coverage == 255) {
- qt_memconvert(dest, buffer, l);
- } else if (sizeof(DST) == 3 && sizeof(SRC) == 3 && l >= 4 &&
- (quintptr(dest) & 3) == (quintptr(buffer) & 3))
- {
- blendUntransformed_dest24(dest, buffer, coverage, l);
- } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 &&
- (quintptr(dest) & 3) == (quintptr(buffer) & 3)) {
- blendUntransformed_dest16(dest, buffer, coverage, l);
- } else {
- blendUntransformed_unaligned(dest, buffer, coverage, l);
- }
+
+ if (ialpha != 0)
+ blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha);
dest += l;
length -= l;
@@ -5805,74 +4759,12 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans,
}
}
-static void blend_transformed_rgb888(int count, const QSpan *spans,
- void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_argb6666(int count, const QSpan *spans,
- void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_rgb666(int count, const QSpan *spans,
- void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_argb8565(int count, const QSpan *spans,
- void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_rgb565(int count, const QSpan *spans,
- void *userData)
-{
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
- blendTransformed<qrgb565, qargb8565>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB16)
- blendTransformed<qrgb565, qrgb565>(count, spans, userData);
- else
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_argb8555(int count, const QSpan *spans,
- void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_rgb555(int count, const QSpan *spans,
- void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_argb4444(int count, const QSpan *spans,
- void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_rgb444(int count, const QSpan *spans,
- void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-template <SpanMethod spanMethod>
-Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_tiled_argb(int count, const QSpan *spans, void *userData)
+void blend_transformed_tiled_argb(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format != QImage::Format_ARGB32_Premultiplied
&& data->texture.format != QImage::Format_RGB32) {
- blend_src_generic<spanMethod>(count, spans, userData);
+ blend_src_generic(count, spans, userData);
return;
}
@@ -5925,12 +4817,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_tiled_argb(int count, const QS
y += fdy;
++b;
}
- if (spanMethod == RegularSpans)
- func(target, buffer, l, coverage);
- else
- drawBufferSpan(data, buffer, buffer_size,
- spans->x + spans->len - length,
- spans->y, l, coverage);
+ func(target, buffer, l, coverage);
target += l;
length -= l;
}
@@ -5985,12 +4872,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_tiled_argb(int count, const QS
}
++b;
}
- if (spanMethod == RegularSpans)
- func(target, buffer, l, coverage);
- else
- drawBufferSpan(data, buffer, buffer_size,
- spans->x + spans->len - length,
- spans->y, l, coverage);
+ func(target, buffer, l, coverage);
target += l;
length -= l;
}
@@ -5999,18 +4881,20 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_tiled_argb(int count, const QS
}
}
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *spans, void *userData)
+void blend_transformed_tiled_rgb565(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData*>(userData);
QPainter::CompositionMode mode = data->rasterBuffer->compositionMode;
- if (mode != QPainter::CompositionMode_SourceOver) {
- blend_src_generic<RegularSpans>(count, spans, userData);
+ if (data->texture.format != QImage::Format_RGB16
+ || (mode != QPainter::CompositionMode_SourceOver
+ && mode != QPainter::CompositionMode_Source))
+ {
+ blend_src_generic(count, spans, userData);
return;
}
- SRC buffer[buffer_size];
+ quint16 buffer[buffer_size];
const int image_width = data->texture.width;
const int image_height = data->texture.height;
@@ -6021,13 +4905,14 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp
while (count--) {
const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8;
- if (coverage == 0) {
+ const quint8 alpha = (coverage + 1) >> 3;
+ const quint8 ialpha = 0x20 - alpha;
+ if (alpha == 0) {
++spans;
continue;
}
- DST *dest = (DST*)data->rasterBuffer->scanLine(spans->y)
- + spans->x;
+ quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x;
const qreal cx = spans->x + qreal(0.5);
const qreal cy = spans->y + qreal(0.5);
int x = int((data->m21 * cy
@@ -6037,10 +4922,17 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp
int length = spans->len;
while (length) {
- const int l = qMin(length, buffer_size);
+ int l;
+ quint16 *b;
+ if (ialpha == 0) {
+ l = length;
+ b = dest;
+ } else {
+ l = qMin(length, buffer_size);
+ b = buffer;
+ }
+ const quint16 *end = b + l;
- const SRC *end = buffer + l;
- SRC *b = buffer;
while (b < end) {
int px = (x >> 16) % image_width;
int py = (y >> 16) % image_height;
@@ -6050,25 +4942,15 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp
if (py < 0)
py += image_height;
- *b = ((SRC*)data->texture.scanLine(py))[px];
+ *b = ((quint16 *)data->texture.scanLine(py))[px];
++b;
x += fdx;
y += fdy;
}
- if (!SRC::hasAlpha() && coverage == 255) {
- qt_memconvert(dest, buffer, l);
- } else if (sizeof(DST) == 3 && sizeof(SRC) == 3 && l >= 4 &&
- (quintptr(dest) & 3) == (quintptr(buffer) & 3))
- {
- blendUntransformed_dest24(dest, buffer, coverage, l);
- } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 &&
- (quintptr(dest) & 3) == (quintptr(buffer) & 3)) {
- blendUntransformed_dest16(dest, buffer, coverage, l);
- } else {
- blendUntransformed_unaligned(dest, buffer, coverage, l);
- }
+ if (ialpha != 0)
+ blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha);
dest += l;
length -= l;
@@ -6082,13 +4964,14 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp
while (count--) {
const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8;
- if (coverage == 0) {
+ const quint8 alpha = (coverage + 1) >> 3;
+ const quint8 ialpha = 0x20 - alpha;
+ if (alpha == 0) {
++spans;
continue;
}
- DST *dest = (DST*)data->rasterBuffer->scanLine(spans->y)
- + spans->x;
+ quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x;
const qreal cx = spans->x + qreal(0.5);
const qreal cy = spans->y + qreal(0.5);
@@ -6099,9 +4982,17 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp
int length = spans->len;
while (length) {
- const int l = qMin(length, buffer_size);
- const SRC *end = buffer + l;
- SRC *b = buffer;
+ int l;
+ quint16 *b;
+ if (ialpha == 0) {
+ l = length;
+ b = dest;
+ } else {
+ l = qMin(length, buffer_size);
+ b = buffer;
+ }
+ const quint16 *end = b + l;
+
while (b < end) {
const qreal iw = w == 0 ? 1 : 1 / w;
const qreal tx = x * iw;
@@ -6117,7 +5008,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp
if (py < 0)
py += image_height;
- *b = ((SRC*)data->texture.scanLine(py))[px];
+ *b = ((quint16 *)data->texture.scanLine(py))[px];
++b;
x += fdx;
@@ -6127,18 +5018,9 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp
if (!w)
w += fdw;
}
- if (!SRC::hasAlpha() && coverage == 255) {
- qt_memconvert(dest, buffer, l);
- } else if (sizeof(DST) == 3 && sizeof(SRC) == 3 && l >= 4 &&
- (quintptr(dest) & 3) == (quintptr(buffer) & 3))
- {
- blendUntransformed_dest24(dest, buffer, coverage, l);
- } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 &&
- (quintptr(dest) & 3) == (quintptr(buffer) & 3)) {
- blendUntransformed_dest16(dest, buffer, coverage, l);
- } else {
- blendUntransformed_unaligned(dest, buffer, coverage, l);
- }
+
+ if (ialpha != 0)
+ blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha);
dest += l;
length -= l;
@@ -6148,185 +5030,122 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp
}
}
-static void blend_transformed_tiled_rgb888(int count, const QSpan *spans,
- void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_tiled_argb6666(int count, const QSpan *spans,
- void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_tiled_rgb666(int count, const QSpan *spans,
- void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_tiled_argb8565(int count, const QSpan *spans,
- void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_tiled_rgb565(int count, const QSpan *spans,
- void *userData)
-{
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
- blendTransformedTiled<qrgb565, qargb8565>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB16)
- blendTransformedTiled<qrgb565, qrgb565>(count, spans, userData);
- else
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_tiled_argb8555(int count, const QSpan *spans,
- void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_tiled_rgb555(int count, const QSpan *spans,
- void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_tiled_argb4444(int count, const QSpan *spans,
- void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-static void blend_transformed_tiled_rgb444(int count, const QSpan *spans,
- void *userData)
-{
- blend_src_generic<RegularSpans>(count, spans, userData);
-}
-
-# define SPANFUNC_POINTER(Name, Arg) Name<Arg>
-
/* Image formats here are target formats */
static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats] = {
// Untransformed
{
0, // Invalid
- SPANFUNC_POINTER(blend_untransformed_generic, RegularSpans), // Mono
- SPANFUNC_POINTER(blend_untransformed_generic, RegularSpans), // MonoLsb
- SPANFUNC_POINTER(blend_untransformed_generic, RegularSpans), // Indexed8
- SPANFUNC_POINTER(blend_untransformed_generic, RegularSpans), // RGB32
- SPANFUNC_POINTER(blend_untransformed_generic, RegularSpans), // ARGB32
- SPANFUNC_POINTER(blend_untransformed_argb, RegularSpans), // ARGB32_Premultiplied
+ blend_untransformed_generic, // Mono
+ blend_untransformed_generic, // MonoLsb
+ blend_untransformed_generic, // Indexed8
+ blend_untransformed_generic, // RGB32
+ blend_untransformed_generic, // ARGB32
+ blend_untransformed_argb, // ARGB32_Premultiplied
blend_untransformed_rgb565,
- blend_untransformed_argb8565,
- blend_untransformed_rgb666,
- blend_untransformed_argb6666,
- blend_untransformed_rgb555,
- blend_untransformed_argb8555,
- blend_untransformed_rgb888,
- blend_untransformed_rgb444,
- blend_untransformed_argb4444,
+ blend_untransformed_generic,
+ blend_untransformed_generic,
+ blend_untransformed_generic,
+ blend_untransformed_generic,
+ blend_untransformed_generic,
+ blend_untransformed_generic,
+ blend_untransformed_generic,
+ blend_untransformed_generic,
},
// Tiled
{
0, // Invalid
- SPANFUNC_POINTER(blend_tiled_generic, RegularSpans), // Mono
- SPANFUNC_POINTER(blend_tiled_generic, RegularSpans), // MonoLsb
- SPANFUNC_POINTER(blend_tiled_generic, RegularSpans), // Indexed8
- SPANFUNC_POINTER(blend_tiled_generic, RegularSpans), // RGB32
- SPANFUNC_POINTER(blend_tiled_generic, RegularSpans), // ARGB32
- SPANFUNC_POINTER(blend_tiled_argb, RegularSpans), // ARGB32_Premultiplied
+ blend_tiled_generic, // Mono
+ blend_tiled_generic, // MonoLsb
+ blend_tiled_generic, // Indexed8
+ blend_tiled_generic, // RGB32
+ blend_tiled_generic, // ARGB32
+ blend_tiled_argb, // ARGB32_Premultiplied
blend_tiled_rgb565,
- blend_tiled_argb8565,
- blend_tiled_rgb666,
- blend_tiled_argb6666,
- blend_tiled_rgb555,
- blend_tiled_argb8555,
- blend_tiled_rgb888,
- blend_tiled_rgb444,
- blend_tiled_argb4444,
+ blend_tiled_generic,
+ blend_tiled_generic,
+ blend_tiled_generic,
+ blend_tiled_generic,
+ blend_tiled_generic,
+ blend_tiled_generic,
+ blend_tiled_generic,
+ blend_tiled_generic,
},
// Transformed
{
0, // Invalid
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Mono
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // MonoLsb
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Indexed8
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32
- SPANFUNC_POINTER(blend_transformed_argb, RegularSpans), // ARGB32_Premultiplied
+ blend_src_generic, // Mono
+ blend_src_generic, // MonoLsb
+ blend_src_generic, // Indexed8
+ blend_src_generic, // RGB32
+ blend_src_generic, // ARGB32
+ blend_transformed_argb, // ARGB32_Premultiplied
blend_transformed_rgb565,
- blend_transformed_argb8565,
- blend_transformed_rgb666,
- blend_transformed_argb6666,
- blend_transformed_rgb555,
- blend_transformed_argb8555,
- blend_transformed_rgb888,
- blend_transformed_rgb444,
- blend_transformed_argb4444,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
},
// TransformedTiled
{
0,
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Mono
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // MonoLsb
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Indexed8
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32
- SPANFUNC_POINTER(blend_transformed_tiled_argb, RegularSpans), // ARGB32_Premultiplied
+ blend_src_generic, // Mono
+ blend_src_generic, // MonoLsb
+ blend_src_generic, // Indexed8
+ blend_src_generic, // RGB32
+ blend_src_generic, // ARGB32
+ blend_transformed_tiled_argb, // ARGB32_Premultiplied
blend_transformed_tiled_rgb565,
- blend_transformed_tiled_argb8565,
- blend_transformed_tiled_rgb666,
- blend_transformed_tiled_argb6666,
- blend_transformed_tiled_rgb555,
- blend_transformed_tiled_argb8555,
- blend_transformed_tiled_rgb888,
- blend_transformed_tiled_rgb444,
- blend_transformed_tiled_argb4444
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic
},
// Bilinear
{
0,
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Mono
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // MonoLsb
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Indexed8
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32_Premultiplied
+ blend_src_generic, // Mono
+ blend_src_generic, // MonoLsb
+ blend_src_generic, // Indexed8
+ blend_src_generic, // RGB32
+ blend_src_generic, // ARGB32
+ blend_src_generic, // ARGB32_Premultiplied
blend_transformed_bilinear_rgb565,
- blend_transformed_bilinear_argb8565,
- blend_transformed_bilinear_rgb666,
- blend_transformed_bilinear_argb6666,
- blend_transformed_bilinear_rgb555,
- blend_transformed_bilinear_argb8555,
- blend_transformed_bilinear_rgb888,
- blend_transformed_bilinear_rgb444,
- blend_transformed_bilinear_argb4444,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
+ blend_src_generic,
},
// BilinearTiled
{
0,
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Mono
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // MonoLsb
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Indexed8
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32_Premultiplied
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB16
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB8565_Premultiplied
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB666
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB6666_Premultiplied
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB555
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB8555_Premultiplied
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB888
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB444
- SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB4444_Premultiplied
+ blend_src_generic, // Mono
+ blend_src_generic, // MonoLsb
+ blend_src_generic, // Indexed8
+ blend_src_generic, // RGB32
+ blend_src_generic, // ARGB32
+ blend_src_generic, // ARGB32_Premultiplied
+ blend_src_generic, // RGB16
+ blend_src_generic, // ARGB8565_Premultiplied
+ blend_src_generic, // RGB666
+ blend_src_generic, // ARGB6666_Premultiplied
+ blend_src_generic, // RGB555
+ blend_src_generic, // ARGB8555_Premultiplied
+ blend_src_generic, // RGB888
+ blend_src_generic, // RGB444
+ blend_src_generic, // ARGB4444_Premultiplied
}
};
@@ -6339,14 +5158,11 @@ void qBlendTexture(int count, const QSpan *spans, void *userData)
template <class DST>
inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer,
- int x, int y, quint32 color,
+ int x, int y, DST color,
const uchar *map,
- int mapWidth, int mapHeight, int mapStride,
- DST dummy = 0)
+ int mapWidth, int mapHeight, int mapStride)
{
- Q_UNUSED(dummy);
- const DST c = qt_colorConvert<DST, quint32>(color, 0);
- DST *dest = reinterpret_cast<DST*>(rasterBuffer->scanLine(y)) + x;
+ DST *dest = reinterpret_cast<DST *>(rasterBuffer->scanLine(y)) + x;
const int destStride = rasterBuffer->bytesPerLine() / sizeof(DST);
if (mapWidth > 8) {
@@ -6360,7 +5176,7 @@ inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer,
++n;
} else {
if (n) {
- qt_memfill(dest + x0, c, n);
+ qt_memfill(dest + x0, color, n);
x0 += n + 1;
n = 0;
} else {
@@ -6375,7 +5191,7 @@ inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer,
}
}
if (n)
- qt_memfill(dest + x0, c, n);
+ qt_memfill(dest + x0, color, n);
dest += destStride;
map += mapStride;
}
@@ -6387,7 +5203,7 @@ inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer,
if (s & 0x80) {
++n;
} else if (n) {
- qt_memfill(dest + x0, c, n);
+ qt_memfill(dest + x0, color, n);
x0 += n + 1;
n = 0;
} else {
@@ -6395,7 +5211,7 @@ inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer,
}
}
if (n)
- qt_memfill(dest + x0, c, n);
+ qt_memfill(dest + x0, color, n);
dest += destStride;
map += mapStride;
}
@@ -6448,7 +5264,7 @@ static void qt_gradient_quint32(int count, const QSpan *spans, void *userData)
}
} else {
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic(count, spans, userData);
}
}
@@ -6496,7 +5312,7 @@ static void qt_gradient_quint16(int count, const QSpan *spans, void *userData)
data->solid.color = oldColor;
} else {
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic(count, spans, userData);
}
}
@@ -6514,7 +5330,7 @@ inline static void qt_bitmapblit_quint16(QRasterBuffer *rasterBuffer,
const uchar *map,
int mapWidth, int mapHeight, int mapStride)
{
- qt_bitmapblit_template<quint16>(rasterBuffer, x, y, color,
+ qt_bitmapblit_template<quint16>(rasterBuffer, x, y, qConvertRgb32To16(color),
map, mapWidth, mapHeight, mapStride);
}
@@ -6572,7 +5388,7 @@ static void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer,
int mapWidth, int mapHeight, int mapStride,
const QClipData *)
{
- const quint16 c = qt_colorConvert<quint16, quint32>(color, 0);
+ const quint16 c = qConvertRgb32To16(color);
quint16 *dest = reinterpret_cast<quint16*>(rasterBuffer->scanLine(y)) + x;
const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint16);
@@ -6838,41 +5654,25 @@ static void qt_alphargbblit_quint32(QRasterBuffer *rasterBuffer,
}
}
-template <class T>
-inline void qt_rectfill_template(QRasterBuffer *rasterBuffer,
- int x, int y, int width, int height,
- quint32 color, T dummy = 0)
+static void qt_rectfill_quint32(QRasterBuffer *rasterBuffer,
+ int x, int y, int width, int height,
+ quint32 color)
{
- Q_UNUSED(dummy);
-
- qt_rectfill<T>(reinterpret_cast<T*>(rasterBuffer->buffer()),
- qt_colorConvert<T, quint32p>(quint32p::fromRawData(color), 0),
- x, y, width, height, rasterBuffer->bytesPerLine());
+ qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
+ color, x, y, width, height, rasterBuffer->bytesPerLine());
}
-#define QT_RECTFILL(T) \
- inline static void qt_rectfill_##T(QRasterBuffer *rasterBuffer, \
- int x, int y, int width, int height, \
- quint32 color) \
- { \
- qt_rectfill_template<T>(rasterBuffer, x, y, width, height, color); \
- }
-
-QT_RECTFILL(quint32)
-QT_RECTFILL(quint16)
-QT_RECTFILL(qargb8565)
-QT_RECTFILL(qrgb666)
-QT_RECTFILL(qargb6666)
-QT_RECTFILL(qrgb555)
-QT_RECTFILL(qargb8555)
-QT_RECTFILL(qrgb888)
-QT_RECTFILL(qrgb444)
-QT_RECTFILL(qargb4444)
-#undef QT_RECTFILL
+static void qt_rectfill_quint16(QRasterBuffer *rasterBuffer,
+ int x, int y, int width, int height,
+ quint32 color)
+{
+ qt_rectfill<quint16>(reinterpret_cast<quint16 *>(rasterBuffer->buffer()),
+ qConvertRgb32To16(color), x, y, width, height, rasterBuffer->bytesPerLine());
+}
-inline static void qt_rectfill_nonpremul_quint32(QRasterBuffer *rasterBuffer,
- int x, int y, int width, int height,
- quint32 color)
+static void qt_rectfill_nonpremul_quint32(QRasterBuffer *rasterBuffer,
+ int x, int y, int width, int height,
+ quint32 color)
{
qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
INV_PREMUL(color), x, y, width, height, rasterBuffer->bytesPerLine());
@@ -6889,19 +5689,19 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_Mono,
{
blend_color_generic,
- SPANFUNC_POINTER(blend_src_generic, RegularSpans),
+ blend_src_generic,
0, 0, 0, 0
},
// Format_MonoLSB,
{
blend_color_generic,
- SPANFUNC_POINTER(blend_src_generic, RegularSpans),
+ blend_src_generic,
0, 0, 0, 0
},
// Format_Indexed8,
{
blend_color_generic,
- SPANFUNC_POINTER(blend_src_generic, RegularSpans),
+ blend_src_generic,
0, 0, 0, 0
},
// Format_RGB32,
@@ -6942,88 +5742,78 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
},
// Format_ARGB8565_Premultiplied
{
- SPANFUNC_POINTER_BLENDCOLOR(qargb8565),
- SPANFUNC_POINTER(blend_src_generic, RegularSpans),
- 0, 0, 0,
- qt_rectfill_qargb8565
+ blend_color_generic,
+ blend_src_generic,
+ 0, 0, 0, 0
},
// Format_RGB666
{
- SPANFUNC_POINTER_BLENDCOLOR(qrgb666),
- SPANFUNC_POINTER(blend_src_generic, RegularSpans),
- 0, 0, 0,
- qt_rectfill_qrgb666
+ blend_color_generic,
+ blend_src_generic,
+ 0, 0, 0, 0
},
// Format_ARGB6666_Premultiplied
{
- SPANFUNC_POINTER_BLENDCOLOR(qargb6666),
- SPANFUNC_POINTER(blend_src_generic, RegularSpans),
- 0, 0, 0,
- qt_rectfill_qargb6666
+ blend_color_generic,
+ blend_src_generic,
+ 0, 0, 0, 0
},
// Format_RGB555
{
- SPANFUNC_POINTER_BLENDCOLOR(qrgb555),
- SPANFUNC_POINTER(blend_src_generic, RegularSpans),
- 0, 0, 0,
- qt_rectfill_qrgb555
+ blend_color_generic,
+ blend_src_generic,
+ 0, 0, 0, 0
},
// Format_ARGB8555_Premultiplied
{
- SPANFUNC_POINTER_BLENDCOLOR(qargb8555),
- SPANFUNC_POINTER(blend_src_generic, RegularSpans),
- 0, 0, 0,
- qt_rectfill_qargb8555
+ blend_color_generic,
+ blend_src_generic,
+ 0, 0, 0, 0
},
// Format_RGB888
{
- SPANFUNC_POINTER_BLENDCOLOR(qrgb888),
- SPANFUNC_POINTER(blend_src_generic, RegularSpans),
- 0, 0, 0,
- qt_rectfill_qrgb888
+ blend_color_generic,
+ blend_src_generic,
+ 0, 0, 0, 0
},
// Format_RGB444
{
- SPANFUNC_POINTER_BLENDCOLOR(qrgb444),
- SPANFUNC_POINTER(blend_src_generic, RegularSpans),
- 0, 0, 0,
- qt_rectfill_qrgb444
+ blend_color_generic,
+ blend_src_generic,
+ 0, 0, 0, 0
},
// Format_ARGB4444_Premultiplied
{
- SPANFUNC_POINTER_BLENDCOLOR(qargb4444),
- SPANFUNC_POINTER(blend_src_generic, RegularSpans),
- 0, 0, 0,
- qt_rectfill_qargb4444
+ blend_color_generic,
+ blend_src_generic,
+ 0, 0, 0, 0
}
};
#if defined(Q_CC_MSVC) && !defined(_MIPS_)
-template <class DST, class SRC>
-inline void qt_memfill_template(DST *dest, SRC color, int count)
+template <class T>
+inline void qt_memfill_template(T *dest, T color, int count)
{
- const DST c = qt_colorConvert<DST, SRC>(color, 0);
while (count--)
- *dest++ = c;
+ *dest++ = color;
}
#else
-template <class DST, class SRC>
-inline void qt_memfill_template(DST *dest, SRC color, int count)
+template <class T>
+inline void qt_memfill_template(T *dest, T color, int count)
{
- const DST c = qt_colorConvert<DST, SRC>(color, 0);
int n = (count + 7) / 8;
switch (count & 0x07)
{
- case 0: do { *dest++ = c;
- case 7: *dest++ = c;
- case 6: *dest++ = c;
- case 5: *dest++ = c;
- case 4: *dest++ = c;
- case 3: *dest++ = c;
- case 2: *dest++ = c;
- case 1: *dest++ = c;
+ case 0: do { *dest++ = color;
+ case 7: *dest++ = color;
+ case 6: *dest++ = color;
+ case 5: *dest++ = color;
+ case 4: *dest++ = color;
+ case 3: *dest++ = color;
+ case 2: *dest++ = color;
+ case 1: *dest++ = color;
} while (--n > 0);
}
}
@@ -7053,7 +5843,7 @@ inline void qt_memfill_template(quint16 *dest, quint16 value, int count)
static void qt_memfill_quint16(quint16 *dest, quint16 color, int count)
{
- qt_memfill_template<quint16, quint16>(dest, color, count);
+ qt_memfill_template<quint16>(dest, color, count);
}
typedef void (*qt_memfill32_func)(quint32 *dest, quint32 value, int count);
@@ -7067,8 +5857,8 @@ qt_memfill16_func qt_memfill16 = qt_memfill16_setup;
void qInitDrawhelperAsm()
{
- qt_memfill32 = qt_memfill_template<quint32, quint32>;
- qt_memfill16 = qt_memfill_quint16; //qt_memfill_template<quint16, quint16>;
+ qt_memfill32 = qt_memfill_template<quint32>;
+ qt_memfill16 = qt_memfill_quint16; //qt_memfill_template<quint16>;
CompositionFunction *functionForModeAsm = 0;
CompositionFunctionSolid *functionForModeSolidAsm = 0;
diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp
index c3dd4fb1ef..895b44dc17 100644
--- a/src/gui/painting/qdrawhelper_neon.cpp
+++ b/src/gui/painting/qdrawhelper_neon.cpp
@@ -198,7 +198,7 @@ void qt_blend_rgb16_on_argb32_neon(uchar *destPixels, int dbpl,
while (h--) {
for (int x=0; x<w; ++x)
- dst[x] = INTERPOLATE_PIXEL_255(qt_colorConvert(src[x], dst[x]), a, dst[x], ia);
+ dst[x] = INTERPOLATE_PIXEL_255(qConvertRgb16To32(src[x]), a, dst[x], ia);
dst += dbpl;
src += sbpl;
}
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index bf8eadcc03..2e88fe718a 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -657,1059 +657,22 @@ Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16_32(uint x, uint a) {
| (((255*qGreen(p)) / qAlpha(p)) << 8) \
| ((255*qBlue(p)) / qAlpha(p))))
-template <class DST, class SRC>
-inline DST qt_colorConvert(SRC color, DST dummy)
-{
- Q_UNUSED(dummy);
- return DST(color);
-}
-
-
-template <>
-inline quint32 qt_colorConvert(quint16 color, quint32 dummy)
-{
- Q_UNUSED(dummy);
- const int r = (color & 0xf800);
- const int g = (color & 0x07e0);
- const int b = (color & 0x001f);
- const int tr = (r >> 8) | (r >> 13);
- const int tg = (g >> 3) | (g >> 9);
- const int tb = (b << 3) | (b >> 2);
-
- return qRgb(tr, tg, tb);
-}
-
-template <>
-inline quint16 qt_colorConvert(quint32 color, quint16 dummy)
-{
- Q_UNUSED(dummy);
- const int r = qRed(color) << 8;
- const int g = qGreen(color) << 3;
- const int b = qBlue(color) >> 3;
-
- return (r & 0xf800) | (g & 0x07e0)| (b & 0x001f);
-}
-
-class quint32p
-{
-public:
- inline quint32p(quint32 v) : data(PREMUL(v)) {}
-
- inline operator quint32() const { return data; }
-
- inline operator quint16() const
- {
- return qt_colorConvert<quint16, quint32>(data, 0);
- }
-
- Q_STATIC_INLINE_FUNCTION quint32p fromRawData(quint32 v)
- {
- quint32p p;
- p.data = v;
- return p;
- }
-
-private:
- quint32p() {}
- quint32 data;
-} Q_PACKED;
-
-class qabgr8888
-{
-public:
- inline qabgr8888(quint32 v)
- {
- data = qRgba(qBlue(v), qGreen(v), qRed(v), qAlpha(v));
- }
-
- inline bool operator==(const qabgr8888 &v) const { return data == v.data; }
-
-private:
- quint32 data;
-} Q_PACKED;
-
-class qrgb565;
-
-class qargb8565
-{
-public:
- Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return true; }
-
- inline qargb8565() {}
- inline qargb8565(quint32 v);
- inline explicit qargb8565(quint32p v);
- inline qargb8565(const qargb8565 &v);
- inline qargb8565(const qrgb565 &v);
-
- inline operator quint32() const;
- inline operator quint16() const;
-
- inline quint8 alpha() const { return data[0]; }
- inline qargb8565 truncedAlpha() {
- data[0] &= 0xf8;
- data[1] &= 0xdf;
- return *this;
- }
- Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 3; }
- Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x20 - alpha(a); }
-
- inline qargb8565 byte_mul(quint8 a) const;
- inline qargb8565 operator+(qargb8565 v) const;
- inline bool operator==(const qargb8565 &v) const;
-
- inline quint32 rawValue() const;
- inline quint16 rawValue16() const;
-
-private:
- friend class qrgb565;
-
- quint8 data[3];
-} Q_PACKED;
-
-class qrgb565
-{
-public:
- Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return false; }
-
- qrgb565(int v = 0) : data(v) {}
-
- inline explicit qrgb565(quint32p v);
- inline explicit qrgb565(quint32 v);
- inline explicit qrgb565(const qargb8565 &v);
-
- inline operator quint32() const;
- inline operator quint16() const;
-
- inline qrgb565 operator+(qrgb565 v) const;
-
- inline quint8 alpha() const { return 0xff; }
- inline qrgb565 truncedAlpha() { return *this; }
- Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 3; }
- Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x20 - alpha(a); }
-
- inline qrgb565 byte_mul(quint8 a) const;
-
- inline bool operator==(const qrgb565 &v) const;
- inline quint16 rawValue() const { return data; }
-
-private:
- friend class qargb8565;
-
- quint16 data;
-} Q_PACKED;
-
-qargb8565::qargb8565(quint32 v)
-{
- *this = qargb8565(quint32p(v));
-}
-
-qargb8565::qargb8565(quint32p v)
-{
- data[0] = qAlpha(v);
- const int r = qRed(v);
- const int g = qGreen(v);
- const int b = qBlue(v);
- data[1] = ((g << 3) & 0xe0) | (b >> 3);
- data[2] = (r & 0xf8) | (g >> 5);
-}
-
-qargb8565::qargb8565(const qargb8565 &v)
-{
- data[0] = v.data[0];
- data[1] = v.data[1];
- data[2] = v.data[2];
-}
-
-qargb8565::qargb8565(const qrgb565 &v)
-{
- data[0] = 0xff;
- data[1] = v.data & 0xff;
- data[2] = v.data >> 8;
-}
-
-qargb8565::operator quint32() const
-{
- const quint16 rgb = (data[2] << 8) | data[1];
- const int a = data[0];
- const int r = (rgb & 0xf800);
- const int g = (rgb & 0x07e0);
- const int b = (rgb & 0x001f);
- const int tr = qMin(a, (r >> 8) | (r >> 13));
- const int tg = qMin(a, (g >> 3) | (g >> 9));
- const int tb = qMin(a, (b << 3) | (b >> 2));
- return qRgba(tr, tg, tb, data[0]);
-}
-
-qargb8565::operator quint16() const
-{
- return (data[2] << 8) | data[1];
-}
-
-qargb8565 qargb8565::operator+(qargb8565 v) const
-{
- qargb8565 t;
- t.data[0] = data[0] + v.data[0];
- const quint16 rgb = ((data[2] + v.data[2]) << 8)
- + (data[1] + v.data[1]);
- t.data[1] = rgb & 0xff;
- t.data[2] = rgb >> 8;
- return t;
-}
-
-qargb8565 qargb8565::byte_mul(quint8 a) const
-{
- qargb8565 result;
- result.data[0] = (data[0] * a) >> 5;
-
- const quint16 x = (data[2] << 8) | data[1];
- const quint16 t = ((((x & 0x07e0) >> 5) * a) & 0x07e0) |
- ((((x & 0xf81f) * a) >> 5) & 0xf81f);
- result.data[1] = t & 0xff;
- result.data[2] = t >> 8;
- return result;
-}
-
-bool qargb8565::operator==(const qargb8565 &v) const
-{
- return data[0] == v.data[0]
- && data[1] == v.data[1]
- && data[2] == v.data[2];
-}
-
-quint32 qargb8565::rawValue() const
-{
- return (data[2] << 16) | (data[1] << 8) | data[0];
-}
-
-quint16 qargb8565::rawValue16() const
-{
- return (data[2] << 8) | data[1];
-}
-
-qrgb565::qrgb565(quint32p v)
-{
- *this = qrgb565(quint32(v));
-}
-
-qrgb565::qrgb565(quint32 v)
-{
- const int r = qRed(v) << 8;
- const int g = qGreen(v) << 3;
- const int b = qBlue(v) >> 3;
-
- data = (r & 0xf800) | (g & 0x07e0)| (b & 0x001f);
-}
-
-qrgb565::qrgb565(const qargb8565 &v)
-{
- data = (v.data[2] << 8) | v.data[1];
-}
-
-qrgb565::operator quint32() const
-{
- const int r = (data & 0xf800);
- const int g = (data & 0x07e0);
- const int b = (data & 0x001f);
- const int tr = (r >> 8) | (r >> 13);
- const int tg = (g >> 3) | (g >> 9);
- const int tb = (b << 3) | (b >> 2);
- return qRgb(tr, tg, tb);
-}
-
-qrgb565::operator quint16() const
-{
- return data;
-}
-
-qrgb565 qrgb565::operator+(qrgb565 v) const
-{
- qrgb565 t;
- t.data = data + v.data;
- return t;
-}
-
-qrgb565 qrgb565::byte_mul(quint8 a) const
-{
- qrgb565 result;
- result.data = ((((data & 0x07e0) >> 5) * a) & 0x07e0) |
- ((((data & 0xf81f) * a) >> 5) & 0xf81f);
- return result;
-}
-
-bool qrgb565::operator==(const qrgb565 &v) const
-{
- return data == v.data;
-}
-
-class qbgr565
-{
-public:
- inline qbgr565(quint16 v)
- {
- data = ((v & 0x001f) << 11) |
- (v & 0x07e0) |
- ((v & 0xf800) >> 11);
- }
-
- inline bool operator==(const qbgr565 &v) const
- {
- return data == v.data;
- }
-
-private:
- quint16 data;
-} Q_PACKED;
-
-class qrgb555;
-
-class qargb8555
-{
-public:
- Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return true; }
-
- qargb8555() {}
- inline qargb8555(quint32 v);
- inline explicit qargb8555(quint32p v);
- inline qargb8555(const qargb8555 &v);
- inline qargb8555(const qrgb555 &v);
-
- inline operator quint32() const;
-
- inline quint8 alpha() const { return data[0]; }
- inline qargb8555 truncedAlpha() { data[0] &= 0xf8; return *this; }
- Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 3; }
- Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x20 - alpha(a); }
-
- inline qargb8555 operator+(qargb8555 v) const;
- inline qargb8555 byte_mul(quint8 a) const;
-
- inline bool operator==(const qargb8555 &v) const;
-
- inline quint32 rawValue() const;
-
-private:
- friend class qrgb555;
- quint8 data[3];
-} Q_PACKED;
-
-class qrgb555
-{
-public:
- Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return false; }
-
- inline qrgb555(int v = 0) : data(v) {}
-
- inline explicit qrgb555(quint32p v) { *this = qrgb555(quint32(v)); }
-
- inline explicit qrgb555(quint32 v)
- {
- const int r = qRed(v) << 7;
- const int g = qGreen(v) << 2;
- const int b = qBlue(v) >> 3;
-
- data = (r & 0x7c00) | (g & 0x03e0) | (b & 0x001f);
- }
-
- inline explicit qrgb555(quint16 v)
- {
- data = ((v >> 1) & (0x7c00 | 0x03e0)) |
- (v & 0x001f);
- }
-
- inline explicit qrgb555(const qargb8555 &v);
-
- inline operator quint32() const
- {
- const int r = (data & 0x7c00);
- const int g = (data & 0x03e0);
- const int b = (data & 0x001f);
- const int tr = (r >> 7) | (r >> 12);
- const int tg = (g >> 2) | (g >> 7);
- const int tb = (b << 3) | (b >> 2);
-
- return qRgb(tr, tg, tb);
- }
-
- inline operator quint16() const
- {
- const int r = ((data & 0x7c00) << 1) & 0xf800;
- const int g = (((data & 0x03e0) << 1) | ((data >> 4) & 0x0020)) & 0x07e0;
- const int b = (data & 0x001f);
-
- return r | g | b;
- }
-
- inline qrgb555 operator+(qrgb555 v) const;
- inline qrgb555 byte_mul(quint8 a) const;
-
- inline quint8 alpha() const { return 0xff; }
- inline qrgb555 truncedAlpha() { return *this; }
- Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 3; }
- Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x20 - alpha(a); }
-
- inline bool operator==(const qrgb555 &v) const { return v.data == data; }
- inline bool operator!=(const qrgb555 &v) const { return v.data != data; }
-
- inline quint16 rawValue() const { return data; }
-
-private:
- friend class qargb8555;
- friend class qbgr555;
- quint16 data;
-
-} Q_PACKED;
-
-qrgb555::qrgb555(const qargb8555 &v)
-{
- data = (v.data[2] << 8) | v.data[1];
-}
-
-qrgb555 qrgb555::operator+(qrgb555 v) const
-{
- qrgb555 t;
- t.data = data + v.data;
- return t;
-}
-
-qrgb555 qrgb555::byte_mul(quint8 a) const
-{
- quint16 t = (((data & 0x3e0) * a) >> 5) & 0x03e0;
- t |= (((data & 0x7c1f) * a) >> 5) & 0x7c1f;
-
- qrgb555 result;
- result.data = t;
- return result;
-}
-
-class qbgr555
-{
-public:
- inline qbgr555(quint32 v) { *this = qbgr555(qrgb555(v)); }
-
- inline qbgr555(qrgb555 v)
- {
- data = ((v.data & 0x001f) << 10) |
- (v.data & 0x03e0) |
- ((v.data & 0x7c00) >> 10);
- }
-
- inline bool operator==(const qbgr555 &v) const
- {
- return data == v.data;
- }
-
-private:
- quint16 data;
-} Q_PACKED;
-
-qargb8555::qargb8555(quint32 v)
-{
- v = quint32p(v);
- data[0] = qAlpha(v);
- const int r = qRed(v);
- const int g = qGreen(v);
- const int b = qBlue(v);
- data[1] = ((g << 2) & 0xe0) | (b >> 3);
- data[2] = ((r >> 1) & 0x7c) | (g >> 6);
-
-}
-
-qargb8555::qargb8555(quint32p v)
-{
- data[0] = qAlpha(v);
- const int r = qRed(v);
- const int g = qGreen(v);
- const int b = qBlue(v);
- data[1] = ((g << 2) & 0xe0) | (b >> 3);
- data[2] = ((r >> 1) & 0x7c) | (g >> 6);
-}
-
-qargb8555::qargb8555(const qargb8555 &v)
-{
- data[0] = v.data[0];
- data[1] = v.data[1];
- data[2] = v.data[2];
-}
-
-qargb8555::qargb8555(const qrgb555 &v)
-{
- data[0] = 0xff;
- data[1] = v.data & 0xff;
- data[2] = v.data >> 8;
-}
-
-qargb8555::operator quint32() const
-{
- const quint16 rgb = (data[2] << 8) | data[1];
- const int r = (rgb & 0x7c00);
- const int g = (rgb & 0x03e0);
- const int b = (rgb & 0x001f);
- const int tr = (r >> 7) | (r >> 12);
- const int tg = (g >> 2) | (g >> 7);
- const int tb = (b << 3) | (b >> 2);
-
- return qRgba(tr, tg, tb, data[0]);
-}
-
-bool qargb8555::operator==(const qargb8555 &v) const
-{
- return data[0] == v.data[0]
- && data[1] == v.data[1]
- && data[2] == v.data[2];
-}
-
-quint32 qargb8555::rawValue() const
-{
- return (data[2] << 16) | (data[1] << 8) | data[0];
-}
-
-qargb8555 qargb8555::operator+(qargb8555 v) const
-{
- qargb8555 t;
- t.data[0] = data[0] + v.data[0];
- const quint16 rgb = ((data[2] + v.data[2]) << 8)
- + (data[1] + v.data[1]);
- t.data[1] = rgb & 0xff;
- t.data[2] = rgb >> 8;
- return t;
-}
-
-qargb8555 qargb8555::byte_mul(quint8 a) const
-{
- qargb8555 result;
- result.data[0] = (data[0] * a) >> 5;
-
- const quint16 x = (data[2] << 8) | data[1];
- quint16 t = (((x & 0x3e0) * a) >> 5) & 0x03e0;
- t |= (((x & 0x7c1f) * a) >> 5) & 0x7c1f;
- result.data[1] = t & 0xff;
- result.data[2] = t >> 8;
- return result;
-
-}
-
-class qrgb666;
-
-class qargb6666
-{
-public:
- Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return true; }
-
- inline qargb6666() {}
- inline qargb6666(quint32 v) { *this = qargb6666(quint32p(v)); }
- inline explicit qargb6666(quint32p v);
- inline qargb6666(const qargb6666 &v);
- inline qargb6666(const qrgb666 &v);
-
- inline operator quint32 () const;
-
- inline quint8 alpha() const;
- inline qargb6666 truncedAlpha() { return *this; }
- Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 2; }
- Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return (255 - a + 1) >> 2; }
-
- inline qargb6666 byte_mul(quint8 a) const;
- inline qargb6666 operator+(qargb6666 v) const;
- inline bool operator==(const qargb6666 &v) const;
-
- inline quint32 rawValue() const;
-
-private:
- friend class qrgb666;
- quint8 data[3];
-
-} Q_PACKED;
-
-class qrgb666
-{
-public:
- Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return false; }
-
- inline qrgb666() {}
- inline qrgb666(quint32 v);
- inline qrgb666(const qargb6666 &v);
-
- inline operator quint32 () const;
-
- inline quint8 alpha() const { return 0xff; }
- inline qrgb666 truncedAlpha() { return *this; }
- Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 2; }
- Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return (255 - a + 1) >> 2; }
-
- inline qrgb666 operator+(qrgb666 v) const;
- inline qrgb666 byte_mul(quint8 a) const;
-
- inline bool operator==(const qrgb666 &v) const;
- inline bool operator!=(const qrgb666 &v) const { return !(*this == v); }
-
- inline quint32 rawValue() const
- {
- return (data[2] << 16) | (data[1] << 8) | data[0];
- }
-
-private:
- friend class qargb6666;
-
- quint8 data[3];
-} Q_PACKED;
-
-qrgb666::qrgb666(quint32 v)
-{
- const uchar b = qBlue(v);
- const uchar g = qGreen(v);
- const uchar r = qRed(v);
- const uint p = (b >> 2) | ((g >> 2) << 6) | ((r >> 2) << 12);
- data[0] = qBlue(p);
- data[1] = qGreen(p);
- data[2] = qRed(p);
-}
-
-qrgb666::qrgb666(const qargb6666 &v)
-{
- data[0] = v.data[0];
- data[1] = v.data[1];
- data[2] = v.data[2] & 0x03;
-}
-
-qrgb666::operator quint32 () const
-{
- const uchar r = (data[2] << 6) | ((data[1] & 0xf0) >> 2) | (data[2] & 0x3);
- const uchar g = (data[1] << 4) | ((data[0] & 0xc0) >> 4) | ((data[1] & 0x0f) >> 2);
- const uchar b = (data[0] << 2) | ((data[0] & 0x3f) >> 4);
- return qRgb(r, g, b);
-}
-
-qrgb666 qrgb666::operator+(qrgb666 v) const
-{
- const quint32 x1 = (data[2] << 16) | (data[1] << 8) | data[0];
- const quint32 x2 = (v.data[2] << 16) | (v.data[1] << 8) | v.data[0];
- const quint32 t = x1 + x2;
- qrgb666 r;
- r.data[0] = t & 0xff;
- r.data[1] = (t >> 8) & 0xff;
- r.data[2] = (t >> 16) & 0xff;
- return r;
-}
-
-qrgb666 qrgb666::byte_mul(quint8 a) const
-{
- const quint32 x = (data[2] << 16) | (data[1] << 8) | data[0];
- const quint32 t = ((((x & 0x03f03f) * a) >> 6) & 0x03f03f) |
- ((((x & 0x000fc0) * a) >> 6) & 0x000fc0);
-
- qrgb666 r;
- r.data[0] = t & 0xff;
- r.data[1] = (t >> 8) & 0xff;
- r.data[2] = (t >> 16) & 0xff;
- return r;
-}
-
-bool qrgb666::operator==(const qrgb666 &v) const
-{
- return (data[0] == v.data[0] &&
- data[1] == v.data[1] &&
- data[2] == v.data[2]);
-}
-
-qargb6666::qargb6666(quint32p v)
-{
- const quint8 b = qBlue(v) >> 2;
- const quint8 g = qGreen(v) >> 2;
- const quint8 r = qRed(v) >> 2;
- const quint8 a = qAlpha(v) >> 2;
- const uint p = (a << 18) | (r << 12) | (g << 6) | b;
- data[0] = qBlue(p);
- data[1] = qGreen(p);
- data[2] = qRed(p);
-}
-
-qargb6666::qargb6666(const qargb6666 &v)
-{
- data[0] = v.data[0];
- data[1] = v.data[1];
- data[2] = v.data[2];
-}
-
-qargb6666::qargb6666(const qrgb666 &v)
-{
- data[0] = v.data[0];
- data[1] = v.data[1];
- data[2] = (v.data[2] | 0xfc);
-}
-
-qargb6666::operator quint32 () const
-{
- const quint8 r = (data[2] << 6) | ((data[1] & 0xf0) >> 2) | (data[2] & 0x3);
- const quint8 g = (data[1] << 4) | ((data[0] & 0xc0) >> 4) | ((data[1] & 0x0f) >> 2);
- const quint8 b = (data[0] << 2) | ((data[0] & 0x3f) >> 4);
- const quint8 a = (data[2] & 0xfc) | (data[2] >> 6);
- return qRgba(r, g, b, a);
-}
-
-qargb6666 qargb6666::operator+(qargb6666 v) const
-{
- const quint32 x1 = (data[2] << 16) | (data[1] << 8) | data[0];
- const quint32 x2 = (v.data[2] << 16) | (v.data[1] << 8) | v.data[0];
- const quint32 t = x1 + x2;
- qargb6666 r;
- r.data[0] = t & 0xff;
- r.data[1] = (t >> 8) & 0xff;
- r.data[2] = (t >> 16) & 0xff;
- return r;
-}
-
-quint8 qargb6666::alpha() const
-{
- return (data[2] & 0xfc) | (data[2] >> 6);
-}
-
-inline qargb6666 qargb6666::byte_mul(quint8 a) const
-{
- const quint32 x = (data[2] << 16) | (data[1] << 8) | data[0];
- const quint32 t = ((((x & 0x03f03f) * a) >> 6) & 0x03f03f) |
- ((((x & 0xfc0fc0) * a) >> 6) & 0xfc0fc0);
-
- qargb6666 r;
- r.data[0] = t & 0xff;
- r.data[1] = (t >> 8) & 0xff;
- r.data[2] = (t >> 16) & 0xff;
- return r;
-}
-
-bool qargb6666::operator==(const qargb6666 &v) const
-{
- return data[0] == v.data[0]
- && data[1] == v.data[1]
- && data[2] == v.data[2];
-}
-
-quint32 qargb6666::rawValue() const
-{
- return (data[2] << 16) | (data[1] << 8) | data[0];
-}
-
-class qrgb888
-{
-public:
- Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return false; }
-
- inline qrgb888() {}
- inline qrgb888(quint32 v);
-
- inline operator quint32() const;
-
- inline quint8 alpha() const { return 0xff; }
- inline qrgb888 truncedAlpha() { return *this; }
- Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return a; }
- Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 255 - a; }
-
- inline qrgb888 byte_mul(quint8 a) const;
- inline qrgb888 operator+(qrgb888 v) const;
- inline bool operator==(qrgb888 v) const;
-
- inline quint32 rawValue() const;
-
-private:
+struct quint24 {
+ quint24(uint value);
+ operator uint() const;
uchar data[3];
-
} Q_PACKED;
-qrgb888::qrgb888(quint32 v)
+inline quint24::quint24(uint value)
{
- data[0] = qRed(v);
- data[1] = qGreen(v);
- data[2] = qBlue(v);
+ data[0] = uchar(value);
+ data[1] = uchar(value >> 8);
+ data[2] = uchar(value >> 16);
}
-qrgb888::operator quint32() const
+inline quint24::operator uint() const
{
- return qRgb(data[0], data[1], data[2]);
-}
-
-qrgb888 qrgb888::operator+(qrgb888 v) const
-{
- qrgb888 t = *this;
- t.data[0] += v.data[0];
- t.data[1] += v.data[1];
- t.data[2] += v.data[2];
- return t;
-}
-
-qrgb888 qrgb888::byte_mul(quint8 a) const
-{
- quint32 x(*this);
-
- quint32 t = (x & 0xff00ff) * a;
- t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
- t &= 0xff00ff;
-
- x = ((x >> 8) & 0xff00ff) * a;
- x = (x + ((x >> 8) & 0xff00ff) + 0x800080);
- x &= 0xff00ff00;
- x |= t;
- return qrgb888(x);
-}
-
-bool qrgb888::operator==(qrgb888 v) const
-{
- return (data[0] == v.data[0] &&
- data[1] == v.data[1] &&
- data[2] == v.data[2]);
-}
-
-quint32 qrgb888::rawValue() const
-{
- return (data[2] << 16) | (data[1] << 8) | data[0];
-}
-
-template <>
-inline qrgb888 qt_colorConvert(quint32 color, qrgb888 dummy)
-{
- Q_UNUSED(dummy);
- return qrgb888(color);
-}
-
-template <>
-inline quint32 qt_colorConvert(qrgb888 color, quint32 dummy)
-{
- Q_UNUSED(dummy);
- return quint32(color);
-}
-
-// hw: endianess??
-class quint24
-{
-public:
- inline quint24(quint32 v)
- {
- data[0] = qBlue(v);
- data[1] = qGreen(v);
- data[2] = qRed(v);
- }
-
- inline operator quint32 ()
- {
- return qRgb(data[2], data[1], data[0]);
- }
-
- inline bool operator==(const quint24 &v) const
- {
- return data[0] == v.data[0]
- && data[1] == v.data[1]
- && data[2] == v.data[2];
- }
-
-private:
- uchar data[3];
-} Q_PACKED;
-
-template <>
-inline quint24 qt_colorConvert(quint32 color, quint24 dummy)
-{
- Q_UNUSED(dummy);
- return quint24(color);
-}
-
-// hw: endianess??
-class quint18
-{
-public:
- inline quint18(quint32 v)
- {
- uchar b = qBlue(v);
- uchar g = qGreen(v);
- uchar r = qRed(v);
- uint p = (b >> 2) | ((g >> 2) << 6) | ((r >> 2) << 12);
- data[0] = qBlue(p);
- data[1] = qGreen(p);
- data[2] = qRed(p);
- }
-
- inline operator quint32 ()
- {
- const uchar r = (data[2] << 6) | ((data[1] & 0xf0) >> 2) | (data[2] & 0x3);
- const uchar g = (data[1] << 4) | ((data[0] & 0xc0) >> 4) | ((data[1] & 0x0f) >> 2);
- const uchar b = (data[0] << 2) | ((data[0] & 0x3f) >> 4);
- return qRgb(r, g, b);
- }
-
-private:
- uchar data[3];
-} Q_PACKED;
-
-template <>
-inline quint18 qt_colorConvert(quint32 color, quint18 dummy)
-{
- Q_UNUSED(dummy);
- return quint18(color);
-}
-
-class qrgb444;
-
-class qargb4444
-{
-public:
- Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return true; }
-
- inline qargb4444() {}
- inline qargb4444(quint32 v) { *this = qargb4444(quint32p(v)); }
- inline explicit qargb4444(quint32p v);
- inline qargb4444(const qrgb444 &v);
-
- inline operator quint32() const;
- inline operator quint8() const;
-
- inline qargb4444 operator+(qargb4444 v) const;
-
- inline quint8 alpha() const { return ((data & 0xf000) >> 8) | ((data & 0xf000) >> 12); }
- inline qargb4444 truncedAlpha() { return *this; }
- Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 4; }
- Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x10 - alpha(a); }
- inline qargb4444 byte_mul(quint8 a) const;
-
- inline bool operator==(const qargb4444 &v) const { return data == v.data; }
-
- inline quint16 rawValue() const { return data; }
-
-private:
- friend class qrgb444;
- quint16 data;
-
-} Q_PACKED;
-
-class qrgb444
-{
-public:
- Q_STATIC_INLINE_FUNCTION bool hasAlpha() { return false; }
-
- inline qrgb444() {}
- inline qrgb444(quint32 v);
- inline explicit qrgb444(qargb4444 v);
-
- inline operator quint32() const;
- inline operator quint8() const;
-
- inline qrgb444 operator+(qrgb444 v) const;
- inline quint8 alpha() const { return 0xff; }
- inline qrgb444 truncedAlpha() { return *this; }
- Q_STATIC_INLINE_FUNCTION quint8 alpha(quint8 a) { return (a + 1) >> 4; }
- Q_STATIC_INLINE_FUNCTION quint8 ialpha(quint8 a) { return 0x10 - alpha(a); }
- inline qrgb444 byte_mul(quint8 a) const;
-
- inline bool operator==(const qrgb444 &v) const { return data == v.data; }
- inline bool operator!=(const qrgb444 &v) const { return data != v.data; }
-
- inline quint16 rawValue() const { return data; }
-
-private:
- friend class qargb4444;
- quint16 data;
-
-} Q_PACKED;
-
-
-qargb4444::qargb4444(quint32p color)
-{
- quint32 v = color;
- v &= 0xf0f0f0f0;
- const int a = qAlpha(v) << 8;
- const int r = qRed(v) << 4;
- const int g = qGreen(v);
- const int b = qBlue(v) >> 4;
-
- data = a | r | g | b;
-}
-
-qargb4444::qargb4444(const qrgb444 &v)
-{
- data = v.data | 0xf000;
-}
-
-qargb4444::operator quint32() const
-{
- const int a = (data & 0xf000);
- const int r = (data & 0x0f00);
- const int g = (data & 0x00f0);
- const int b = (data & 0x000f);
- const int ta = (a >> 8) | (a >> 12);
- const int tr = (r >> 4) | (r >> 8);
- const int tg = g | (g >> 4);
- const int tb = (b << 4) | b;
-
- return qRgba(tr, tg, tb, ta);
-}
-
-qargb4444::operator quint8() const
-{
- // hw: optimize!
- return qt_colorConvert<quint8, quint32>(operator quint32(), 0);
-}
-
-qargb4444 qargb4444::operator+(qargb4444 v) const
-{
- qargb4444 t;
- t.data = data + v.data;
- return t;
-}
-
-qargb4444 qargb4444::byte_mul(quint8 a) const
-{
- quint16 t = (((data & 0xf0f0) * a) >> 4) & 0xf0f0;
- t |= (((data & 0x0f0f) * a) >> 4) & 0x0f0f;
-
- qargb4444 result;
- result.data = t;
- return result;
-}
-
-qrgb444::qrgb444(quint32 v)
-{
- v &= 0xf0f0f0f0;
- const int r = qRed(v) << 4;
- const int g = qGreen(v);
- const int b = qBlue(v) >> 4;
-
- data = r | g | b;
-}
-
-qrgb444::qrgb444(qargb4444 v)
-{
- data = v.data & 0x0fff;
-}
-
-qrgb444::operator quint32() const
-{
- const int r = (data & 0x0f00);
- const int g = (data & 0x00f0);
- const int b = (data & 0x000f);
- const int tr = (r >> 4) | (r >> 8);
- const int tg = g | (g >> 4);
- const int tb = (b << 4) | b;
-
- return qRgb(tr, tg, tb);
-}
-
-qrgb444::operator quint8() const
-{
- // hw: optimize!
- return qt_colorConvert<quint8, quint32>(operator quint32(), 0);
-}
-
-qrgb444 qrgb444::operator+(qrgb444 v) const
-{
- qrgb444 t;
- t.data = data + v.data;
- return t;
-}
-
-qrgb444 qrgb444::byte_mul(quint8 a) const
-{
- quint16 t = (((data & 0xf0f0) * a) >> 4) & 0xf0f0;
- t |= (((data & 0x0f0f) * a) >> 4) & 0x0f0f;
-
- qrgb444 result;
- result.data = t;
- return result;
+ return data[0] | (data[1] << 8) | (data[2] << 16);
}
template <class T>
@@ -1769,156 +732,6 @@ inline void qt_rectfill(T *dest, T value,
}
}
-template <class DST, class SRC>
-inline void qt_memconvert(DST *dest, const SRC *src, int count)
-{
- if (sizeof(DST) == 1) {
- while (count) {
- int n = 1;
- const SRC color = *src++;
- const DST dstColor = qt_colorConvert<DST, SRC>(color, 0);
- while (--count && (*src == color || dstColor == qt_colorConvert<DST, SRC>(*src, 0))) {
- ++n;
- ++src;
- }
- qt_memfill(dest, dstColor, n);
- dest += n;
- }
- } else {
- /* Duff's device */
- int n = (count + 7) / 8;
- switch (count & 0x07)
- {
- case 0: do { *dest++ = qt_colorConvert<DST, SRC>(*src++, 0);
- case 7: *dest++ = qt_colorConvert<DST, SRC>(*src++, 0);
- case 6: *dest++ = qt_colorConvert<DST, SRC>(*src++, 0);
- case 5: *dest++ = qt_colorConvert<DST, SRC>(*src++, 0);
- case 4: *dest++ = qt_colorConvert<DST, SRC>(*src++, 0);
- case 3: *dest++ = qt_colorConvert<DST, SRC>(*src++, 0);
- case 2: *dest++ = qt_colorConvert<DST, SRC>(*src++, 0);
- case 1: *dest++ = qt_colorConvert<DST, SRC>(*src++, 0);
- } while (--n > 0);
- }
- }
-}
-
-#define QT_TRIVIAL_MEMCONVERT_IMPL(T) \
- template <> \
- inline void qt_memconvert(T *dest, const T *src, int count) \
- { \
- memcpy(dest, src, count * sizeof(T)); \
- }
-QT_TRIVIAL_MEMCONVERT_IMPL(quint32)
-QT_TRIVIAL_MEMCONVERT_IMPL(qrgb888)
-QT_TRIVIAL_MEMCONVERT_IMPL(qargb6666)
-QT_TRIVIAL_MEMCONVERT_IMPL(qrgb666)
-QT_TRIVIAL_MEMCONVERT_IMPL(quint16)
-QT_TRIVIAL_MEMCONVERT_IMPL(qrgb565)
-QT_TRIVIAL_MEMCONVERT_IMPL(qargb8565)
-QT_TRIVIAL_MEMCONVERT_IMPL(qargb8555)
-QT_TRIVIAL_MEMCONVERT_IMPL(qrgb555)
-QT_TRIVIAL_MEMCONVERT_IMPL(qargb4444)
-QT_TRIVIAL_MEMCONVERT_IMPL(qrgb444)
-#undef QT_TRIVIAL_MEMCONVERT_IMPL
-
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
-template <>
-inline void qt_memconvert(qrgb666 *dest, const quint32 *src, int count)
-{
- if (count < 3) {
- switch (count) {
- case 2: *dest++ = qrgb666(*src++);
- case 1: *dest = qrgb666(*src);
- }
- return;
- }
-
- const int align = (quintptr(dest) & 3);
- switch (align) {
- case 1: *dest++ = qrgb666(*src++); --count;
- case 2: *dest++ = qrgb666(*src++); --count;
- case 3: *dest++ = qrgb666(*src++); --count;
- }
-
- quint32 *dest32 = reinterpret_cast<quint32*>(dest);
- int sourceCount = count >> 2;
- while (sourceCount--) {
- dest32[0] = ((src[1] & 0x00000c00) << 20)
- | ((src[1] & 0x000000fc) << 22)
- | ((src[0] & 0x00fc0000) >> 6)
- | ((src[0] & 0x0000fc00) >> 4)
- | ((src[0] & 0x000000fc) >> 2);
- dest32[1] = ((src[2] & 0x003c0000) << 10)
- | ((src[2] & 0x0000fc00) << 12)
- | ((src[2] & 0x000000fc) << 14)
- | ((src[1] & 0x00fc0000) >> 14)
- | ((src[1] & 0x0000f000) >> 12);
- dest32[2] = ((src[3] & 0x00fc0000) << 2)
- | ((src[3] & 0x0000fc00) << 4)
- | ((src[3] & 0x000000fc) << 6)
- | ((src[2] & 0x00c00000) >> 22);
- dest32 += 3;
- src += 4;
- }
-
- dest = reinterpret_cast<qrgb666*>(dest32);
- switch (count & 3) {
- case 3: *dest++ = qrgb666(*src++);
- case 2: *dest++ = qrgb666(*src++);
- case 1: *dest = qrgb666(*src);
- }
-}
-#endif // Q_BYTE_ORDER
-
-template <class T>
-inline void qt_rectcopy(T *dest, const T *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride)
-{
- char *d = (char*)(dest + x) + y * dstStride;
- const char *s = (char*)(src);
- for (int i = 0; i < height; ++i) {
- ::memcpy(d, s, width * sizeof(T));
- d += dstStride;
- s += srcStride;
- }
-}
-
-template <class DST, class SRC>
-inline void qt_rectconvert(DST *dest, const SRC *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride)
-{
- char *d = (char*)(dest + x) + y * dstStride;
- const char *s = (char*)(src);
- for (int i = 0; i < height; ++i) {
- qt_memconvert<DST,SRC>((DST*)d, (const SRC*)s, width);
- d += dstStride;
- s += srcStride;
- }
-}
-
-#define QT_RECTCONVERT_TRIVIAL_IMPL(T) \
- template <> \
- inline void qt_rectconvert(T *dest, const T *src, \
- int x, int y, int width, int height, \
- int dstStride, int srcStride) \
- { \
- qt_rectcopy(dest, src, x, y, width, height, dstStride, srcStride); \
- }
-QT_RECTCONVERT_TRIVIAL_IMPL(quint32)
-QT_RECTCONVERT_TRIVIAL_IMPL(qrgb888)
-QT_RECTCONVERT_TRIVIAL_IMPL(qargb6666)
-QT_RECTCONVERT_TRIVIAL_IMPL(qrgb666)
-QT_RECTCONVERT_TRIVIAL_IMPL(qrgb565)
-QT_RECTCONVERT_TRIVIAL_IMPL(qargb8565)
-QT_RECTCONVERT_TRIVIAL_IMPL(quint16)
-QT_RECTCONVERT_TRIVIAL_IMPL(qargb8555)
-QT_RECTCONVERT_TRIVIAL_IMPL(qrgb555)
-QT_RECTCONVERT_TRIVIAL_IMPL(qargb4444)
-QT_RECTCONVERT_TRIVIAL_IMPL(qrgb444)
-#undef QT_RECTCONVERT_TRIVIAL_IMPL
-
#define QT_MEMFILL_UINT(dest, length, color) \
qt_memfill<quint32>(dest, color, length);
@@ -2137,6 +950,162 @@ void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length, uint color, ui
void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest, int length, uint color, uint const_alpha);
void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest, int length, uint color, uint const_alpha);
+
+struct QPixelLayout;
+typedef const uint *(QT_FASTCALL *ConvertFunc)(uint *buffer, const uint *src, int count,
+ const QPixelLayout *layout, const QRgb *clut);
+
+struct QPixelLayout
+{
+ // Bits per pixel
+ enum BPP {
+ BPPNone,
+ BPP1MSB,
+ BPP1LSB,
+ BPP8,
+ BPP16,
+ BPP24,
+ BPP32,
+ BPPCount
+ };
+
+ // All numbers in bits.
+ uchar redWidth;
+ uchar redShift;
+ uchar greenWidth;
+ uchar greenShift;
+ uchar blueWidth;
+ uchar blueShift;
+ uchar alphaWidth;
+ uchar alphaShift;
+ bool premultiplied;
+ BPP bpp;
+ ConvertFunc convertToARGB32PM;
+ ConvertFunc convertFromARGB32PM;
+};
+
+template <QPixelLayout::BPP bpp>
+uint fetchPixel(const uchar *src, int index);
+
+template <>
+inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP1LSB>(const uchar *src, int index)
+{
+ return (src[index >> 3] >> (index & 7)) & 1;
+}
+
+template <>
+inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP1MSB>(const uchar *src, int index)
+{
+ return (src[index >> 3] >> (~index & 7)) & 1;
+}
+
+template <>
+inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP8>(const uchar *src, int index)
+{
+ return src[index];
+}
+
+template <>
+inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP16>(const uchar *src, int index)
+{
+ return reinterpret_cast<const quint16 *>(src)[index];
+}
+
+template <>
+inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP24>(const uchar *src, int index)
+{
+ return reinterpret_cast<const quint24 *>(src)[index];
+}
+
+template <>
+inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP32>(const uchar *src, int index)
+{
+ return reinterpret_cast<const uint *>(src)[index];
+}
+
+template <QPixelLayout::BPP bpp>
+inline const uint *QT_FASTCALL fetchPixels(uint *buffer, const uchar *src, int index, int count)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = fetchPixel<bpp>(src, index + i);
+ return buffer;
+}
+
+template <>
+inline const uint *QT_FASTCALL fetchPixels<QPixelLayout::BPP32>(uint *, const uchar *src, int index, int)
+{
+ return reinterpret_cast<const uint *>(src) + index;
+}
+
+typedef const uint *(QT_FASTCALL *FetchPixelsFunc)(uint *buffer, const uchar *src, int index, int count);
+
+
+template <QPixelLayout::BPP width>
+void storePixel(uchar *dest, int index, uint pixel);
+
+template <>
+inline void QT_FASTCALL storePixel<QPixelLayout::BPP1LSB>(uchar *dest, int index, uint pixel)
+{
+ if (pixel)
+ dest[index >> 3] |= 1 << (index & 7);
+ else
+ dest[index >> 3] &= ~(1 << (index & 7));
+}
+
+template <>
+inline void QT_FASTCALL storePixel<QPixelLayout::BPP1MSB>(uchar *dest, int index, uint pixel)
+{
+ if (pixel)
+ dest[index >> 3] |= 1 << (~index & 7);
+ else
+ dest[index >> 3] &= ~(1 << (~index & 7));
+}
+
+template <>
+inline void QT_FASTCALL storePixel<QPixelLayout::BPP8>(uchar *dest, int index, uint pixel)
+{
+ dest[index] = uchar(pixel);
+}
+
+template <>
+inline void QT_FASTCALL storePixel<QPixelLayout::BPP16>(uchar *dest, int index, uint pixel)
+{
+ reinterpret_cast<quint16 *>(dest)[index] = quint16(pixel);
+}
+
+template <>
+inline void QT_FASTCALL storePixel<QPixelLayout::BPP24>(uchar *dest, int index, uint pixel)
+{
+ reinterpret_cast<quint24 *>(dest)[index] = quint24(pixel);
+}
+
+template <>
+inline void QT_FASTCALL storePixel<QPixelLayout::BPP32>(uchar *dest, int index, uint pixel)
+{
+ reinterpret_cast<uint *>(dest)[index] = pixel;
+}
+
+template <QPixelLayout::BPP width>
+inline void QT_FASTCALL storePixels(uchar *dest, const uint *src, int index, int count)
+{
+ for (int i = 0; i < count; ++i)
+ storePixel<width>(dest, index + i, src[i]);
+}
+
+template <>
+inline void QT_FASTCALL storePixels<QPixelLayout::BPP32>(uchar *dest, const uint *src, int index, int count)
+{
+ memcpy(reinterpret_cast<uint *>(dest) + index, src, count * sizeof(uint));
+}
+
+typedef void (QT_FASTCALL *StorePixelsFunc)(uchar *dest, const uint *src, int index, int count);
+
+extern QPixelLayout qPixelLayouts[QImage::NImageFormats];
+extern FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount];
+extern StorePixelsFunc qStorePixels[QPixelLayout::BPPCount];
+
+
+
QT_END_NAMESPACE
#endif // QDRAWHELPER_P_H
diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp
index 17b249a235..300a28158d 100644
--- a/src/gui/painting/qdrawhelper_sse2.cpp
+++ b/src/gui/painting/qdrawhelper_sse2.cpp
@@ -459,7 +459,7 @@ void qt_bitmapblit16_sse2(QRasterBuffer *rasterBuffer, int x, int y,
quint32 color,
const uchar *src, int width, int height, int stride)
{
- const quint16 c = qt_colorConvert<quint16, quint32>(color, 0);
+ const quint16 c = qConvertRgb32To16(color);
quint16 *dest = reinterpret_cast<quint16*>(rasterBuffer->scanLine(y)) + x;
const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint16);
diff --git a/src/gui/painting/qdrawhelper_sse_p.h b/src/gui/painting/qdrawhelper_sse_p.h
index 81a5001fb3..494ee70fcb 100644
--- a/src/gui/painting/qdrawhelper_sse_p.h
+++ b/src/gui/painting/qdrawhelper_sse_p.h
@@ -127,7 +127,7 @@ inline void qt_bitmapblit16_sse_template(QRasterBuffer *rasterBuffer,
const uchar *src,
int width, int height, int stride)
{
- const quint16 c = qt_colorConvert<quint16, quint32>(color, 0);
+ const quint16 c = qConvertRgb32To16(color);
quint16 *dest = reinterpret_cast<quint16*>(rasterBuffer->scanLine(y)) + x;
const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint16);
diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp
index 5d027b669b..e6fcc3e5dd 100644
--- a/src/gui/painting/qmemrotate.cpp
+++ b/src/gui/painting/qmemrotate.cpp
@@ -53,36 +53,36 @@ static const int tileSize = 32;
#endif
#endif
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_cachedRead(const SRC *src, int w, int h,
- int sstride,
- DST *dest, int dstride)
+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) {
- DST *destline = reinterpret_cast<DST*>(d + (w - x - 1) * dstride);
- destline[y] = qt_colorConvert<DST,SRC>(src[x], 0);
+ T *destline = reinterpret_cast<T *>(d + (w - x - 1) * dstride);
+ destline[y] = src[x];
}
s += sstride;
- src = reinterpret_cast<const SRC*>(s);
+ src = reinterpret_cast<const T*>(s);
}
}
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_cachedRead(const SRC *src, int w, int h,
- int sstride,
- DST *dest, int dstride)
+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 SRC*>(s);
+ src = reinterpret_cast<const T*>(s);
for (int x = 0; x < w; ++x) {
- DST *destline = reinterpret_cast<DST*>(d + x * dstride);
- destline[h - y - 1] = qt_colorConvert<DST,SRC>(src[x], 0);
+ T *destline = reinterpret_cast<T *>(d + x * dstride);
+ destline[h - y - 1] = src[x];
}
s -= sstride;
}
@@ -90,29 +90,29 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_cachedRead(const SRC *src
#if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_cachedWrite(const SRC *src, int w, int h,
- int sstride,
- DST *dest, int dstride)
+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) {
- DST *d = dest + (w - x - 1) * dstride;
+ T *d = dest + (w - x - 1) * dstride;
for (int y = 0; y < h; ++y) {
- *d++ = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
+ *d++ = src[y * sstride + x];
}
}
}
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_cachedWrite(const SRC *src, int w, int h,
- int sstride,
- DST *dest, int dstride)
+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) {
- DST *d = dest + x * dstride;
+ T *d = dest + x * dstride;
for (int y = h - 1; y >= 0; --y) {
- *d++ = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
+ *d++ = src[y * sstride + x];
}
}
}
@@ -123,23 +123,21 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_cachedWrite(const SRC *sr
// TODO: packing algorithms should probably be modified on 64-bit architectures
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_packing(const SRC *src, int w, int h,
- int sstride,
- DST *dest, int dstride)
+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(SRC);
- dstride /= sizeof(DST);
+ sstride /= sizeof(T);
+ dstride /= sizeof(T);
- const int pack = sizeof(quint32) / sizeof(DST);
- const int unaligned = int((long(dest) & (sizeof(quint32)-1))) / sizeof(DST);
+ 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]
- = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
+ dest[(w - x - 1) * dstride + y] = src[y * sstride + x];
++y;
}
@@ -147,40 +145,36 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_packing(const SRC *src, in
+ unaligned);
const int rest = (h - unaligned) % pack;
while (y < h - rest) {
- quint32 c = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
+ quint32 c = src[y * sstride + x];
for (int i = 1; i < pack; ++i) {
- c |= qt_colorConvert<DST,SRC>(src[(y + i) * sstride + x], 0)
- << (sizeof(int) * 8 / 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]
- = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
+ dest[(w - x - 1) * dstride + y] = src[y * sstride + x];
++y;
}
}
}
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_packing(const SRC *src, int w, int h,
- int sstride,
- DST *dest, int dstride)
+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(SRC);
- dstride /= sizeof(DST);
+ sstride /= sizeof(T);
+ dstride /= sizeof(T);
- const int pack = sizeof(quint32) / sizeof(DST);
- const int unaligned = int((long(dest) & (sizeof(quint32)-1))) / sizeof(DST);
+ 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]
- = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
+ dest[x * dstride + h - y - 1] = src[y * sstride + x];
--y;
}
@@ -188,17 +182,15 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_packing(const SRC *src, i
+ unaligned);
const int rest = (h - unaligned) % pack;
while (y > rest) {
- quint32 c = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
+ quint32 c = src[y * sstride + x];
for (int i = 1; i < pack; ++i) {
- c |= qt_colorConvert<DST,SRC>(src[(y - i) * sstride + x], 0)
- << (sizeof(int) * 8 / 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]
- = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
+ dest[x * dstride + h - y - 1] = src[y * sstride + x];
--y;
}
}
@@ -207,17 +199,16 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_packing(const SRC *src, i
#endif // QT_ROTATION_PACKING
#if QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_tiled(const SRC *src, int w, int h,
- int sstride,
- DST *dest, int dstride)
+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(SRC);
- dstride /= sizeof(DST);
+ sstride /= sizeof(T);
+ dstride /= sizeof(T);
- const int pack = sizeof(quint32) / sizeof(DST);
+ const int pack = sizeof(quint32) / sizeof(T);
const int unaligned =
- qMin(uint((quintptr(dest) & (sizeof(quint32)-1)) / sizeof(DST)), 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;
@@ -230,9 +221,9 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_tiled(const SRC *src, int
if (unaligned) {
for (int x = startx; x >= stopx; --x) {
- DST *d = dest + (w - x - 1) * dstride;
+ T *d = dest + (w - x - 1) * dstride;
for (int y = 0; y < unaligned; ++y) {
- *d++ = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
+ *d++ = src[y * sstride + x];
}
}
}
@@ -244,10 +235,10 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_tiled(const SRC *src, int
for (int x = startx; x >= stopx; --x) {
quint32 *d = reinterpret_cast<quint32*>(dest + (w - x - 1) * dstride + starty);
for (int y = starty; y < stopy; y += pack) {
- quint32 c = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
+ quint32 c = src[y * sstride + x];
for (int i = 1; i < pack; ++i) {
const int shift = (sizeof(int) * 8 / pack * i);
- const DST color = qt_colorConvert<DST,SRC>(src[(y + i) * sstride + x], 0);
+ const T color = src[(y + i) * sstride + x];
c |= color << shift;
}
*d++ = c;
@@ -258,19 +249,19 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_tiled(const SRC *src, int
if (unoptimizedY) {
const int starty = h - unoptimizedY;
for (int x = startx; x >= stopx; --x) {
- DST *d = dest + (w - x - 1) * dstride + starty;
+ T *d = dest + (w - x - 1) * dstride + starty;
for (int y = starty; y < h; ++y) {
- *d++ = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
+ *d++ = src[y * sstride + x];
}
}
}
}
}
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_tiled_unpacked(const SRC *src, int w, int h,
- int sstride,
- DST *dest, int dstride)
+template <class T>
+Q_STATIC_TEMPLATE_FUNCTION
+inline void qt_memrotate90_tiled_unpacked(const T *src, int w, int h, int sstride, T *dest,
+ int dstride)
{
const int numTilesX = (w + tileSize - 1) / tileSize;
const int numTilesY = (h + tileSize - 1) / tileSize;
@@ -284,10 +275,10 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_tiled_unpacked(const SRC *
const int stopy = qMin(starty + tileSize, h);
for (int x = startx; x >= stopx; --x) {
- DST *d = (DST*)((char*)dest + (w - x - 1) * dstride) + starty;
+ T *d = (T *)((char*)dest + (w - x - 1) * dstride) + starty;
const char *s = (const char*)(src + x) + starty * sstride;
for (int y = starty; y < stopy; ++y) {
- *d++ = qt_colorConvert<DST,SRC>(*(const SRC*)(s), 0);
+ *d++ = *(const T *)(s);
s += sstride;
}
}
@@ -295,17 +286,16 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_tiled_unpacked(const SRC *
}
}
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_tiled(const SRC *src, int w, int h,
- int sstride,
- DST *dest, int dstride)
+template <class T>
+Q_STATIC_TEMPLATE_FUNCTION
+inline void qt_memrotate270_tiled(const T *src, int w, int h, int sstride, T *dest, int dstride)
{
- sstride /= sizeof(SRC);
- dstride /= sizeof(DST);
+ sstride /= sizeof(T);
+ dstride /= sizeof(T);
- const int pack = sizeof(quint32) / sizeof(DST);
+ const int pack = sizeof(quint32) / sizeof(T);
const int unaligned =
- qMin(uint((long(dest) & (sizeof(quint32)-1)) / sizeof(DST)), uint(h));
+ qMin(uint((long(dest) & (sizeof(quint32)-1)) / sizeof(T)), uint(h));
const int restX = w % tileSize;
const int restY = (h - unaligned) % tileSize;
const int unoptimizedY = restY % pack;
@@ -318,9 +308,9 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_tiled(const SRC *src, int
if (unaligned) {
for (int x = startx; x < stopx; ++x) {
- DST *d = dest + x * dstride;
+ T *d = dest + x * dstride;
for (int y = h - 1; y >= h - unaligned; --y) {
- *d++ = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
+ *d++ = src[y * sstride + x];
}
}
}
@@ -333,10 +323,10 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_tiled(const SRC *src, int
quint32 *d = reinterpret_cast<quint32*>(dest + x * dstride
+ h - 1 - starty);
for (int y = starty; y > stopy; y -= pack) {
- quint32 c = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
+ quint32 c = src[y * sstride + x];
for (int i = 1; i < pack; ++i) {
const int shift = (sizeof(int) * 8 / pack * i);
- const DST color = qt_colorConvert<DST,SRC>(src[(y - i) * sstride + x], 0);
+ const T color = src[(y - i) * sstride + x];
c |= color << shift;
}
*d++ = c;
@@ -346,19 +336,19 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_tiled(const SRC *src, int
if (unoptimizedY) {
const int starty = unoptimizedY - 1;
for (int x = startx; x < stopx; ++x) {
- DST *d = dest + x * dstride + h - 1 - starty;
+ T *d = dest + x * dstride + h - 1 - starty;
for (int y = starty; y >= 0; --y) {
- *d++ = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
+ *d++ = src[y * sstride + x];
}
}
}
}
}
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_tiled_unpacked(const SRC *src, int w, int h,
- int sstride,
- DST *dest, int dstride)
+template <class T>
+Q_STATIC_TEMPLATE_FUNCTION
+inline void qt_memrotate270_tiled_unpacked(const T *src, int w, int h, int sstride, T *dest,
+ int dstride)
{
const int numTilesX = (w + tileSize - 1) / tileSize;
const int numTilesY = (h + tileSize - 1) / tileSize;
@@ -372,10 +362,10 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_tiled_unpacked(const SRC
const int stopy = qMax(starty - tileSize, 0);
for (int x = startx; x < stopx; ++x) {
- DST *d = (DST*)((char*)dest + x * dstride) + h - 1 - starty;
+ T *d = (T*)((char*)dest + x * dstride) + h - 1 - starty;
const char *s = (const char*)(src + x) + starty * sstride;
for (int y = starty; y >= stopy; --y) {
- *d++ = qt_colorConvert<DST,SRC>(*(const SRC*)s, 0);
+ *d++ = *(const T*)s;
s -= sstride;
}
}
@@ -385,214 +375,112 @@ Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_tiled_unpacked(const SRC
#endif // QT_ROTATION_ALGORITHM
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_template(const SRC *src,
- int srcWidth, int srcHeight, int srcStride,
- DST *dest, int dstStride)
+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<DST,SRC>(src, srcWidth, srcHeight, srcStride,
- dest, dstStride);
+ qt_memrotate90_cachedRead<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
#elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
- qt_memrotate90_cachedWrite<DST,SRC>(src, srcWidth, srcHeight, srcStride,
- dest, dstStride);
+ qt_memrotate90_cachedWrite<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
#elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING
- qt_memrotate90_packing<DST,SRC>(src, srcWidth, srcHeight, srcStride,
- dest, dstStride);
+ qt_memrotate90_packing<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
#elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
- qt_memrotate90_tiled<DST,SRC>(src, srcWidth, srcHeight, srcStride,
- dest, dstStride);
+ qt_memrotate90_tiled<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
#endif
}
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate180_template(const SRC *src,
- int w, int h, int sstride,
- DST *dest, int dstride)
+template <class T>
+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) {
- DST *d = reinterpret_cast<DST*>((char *)(dest) + (h - y - 1) * dstride);
- src = reinterpret_cast<const SRC*>(s);
+ T *d = reinterpret_cast<T*>((char *)(dest) + (h - y - 1) * dstride);
+ src = reinterpret_cast<const T*>(s);
for (int x = w - 1; x >= 0; --x) {
- d[w - x - 1] = qt_colorConvert<DST,SRC>(src[x], 0);
+ d[w - x - 1] = src[x];
}
s -= sstride;
}
}
-template <class DST, class SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_template(const SRC *src,
- int srcWidth, int srcHeight, int srcStride,
- DST *dest, int dstStride)
+template <class T>
+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<DST,SRC>(src, srcWidth, srcHeight, srcStride,
- dest, dstStride);
+ qt_memrotate270_cachedRead<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
#elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
- qt_memrotate270_cachedWrite<DST,SRC>(src, srcWidth, srcHeight, srcStride,
- dest, dstStride);
+ qt_memrotate270_cachedWrite<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
#elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING
- qt_memrotate270_packing<DST,SRC>(src, srcWidth, srcHeight, srcStride,
- dest, dstStride);
+ qt_memrotate270_packing<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
#elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
- qt_memrotate270_tiled_unpacked<DST,SRC>(src, srcWidth, srcHeight,
- srcStride,
- dest, dstStride);
+ qt_memrotate270_tiled_unpacked<T>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
#endif
}
template <>
Q_STATIC_TEMPLATE_SPECIALIZATION
-inline void qt_memrotate90_template<quint24, quint24>(const quint24 *src,
- int srcWidth, int srcHeight, int srcStride,
- quint24 *dest, int dstStride)
+inline void qt_memrotate90_template<quint24>(const quint24 *src, int srcWidth, int srcHeight,
+ int srcStride, quint24 *dest, int dstStride)
{
#if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD
- qt_memrotate90_cachedRead<quint24,quint24>(src, srcWidth, srcHeight,
- srcStride, dest, dstStride);
+ qt_memrotate90_cachedRead<quint24>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
#elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
- qt_memrotate90_cachedWrite<quint24,quint24>(src, srcWidth, srcHeight,
- srcStride, dest, dstStride);
+ 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,quint24>(src, srcWidth, srcHeight,
- srcStride, dest, dstStride);
+ 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,quint24>(src, srcWidth, srcHeight,
- srcStride, dest, dstStride);
+ qt_memrotate90_tiled_unpacked<quint24>(src, srcWidth, srcHeight, srcStride, dest, dstStride);
#endif
}
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline void qt_memrotate90_template<quint24, quint32>(const quint32 *src,
- int srcWidth, int srcHeight, int srcStride,
- quint24 *dest, int dstStride)
-{
-#if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD
- qt_memrotate90_cachedRead<quint24,quint32>(src, srcWidth, srcHeight,
- srcStride, dest, dstStride);
-#elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
- qt_memrotate90_cachedWrite<quint24,quint32>(src, srcWidth, srcHeight,
- srcStride, dest, dstStride);
-#elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING
- // packed algorithm not implemented
- qt_memrotate90_cachedRead<quint24,quint32>(src, srcWidth, srcHeight,
- srcStride, dest, dstStride);
-#elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
- // packed algorithm not implemented
- qt_memrotate90_tiled_unpacked<quint24,quint32>(src, srcWidth, srcHeight,
- srcStride, dest, dstStride);
-#endif
-}
-
-template <>
-Q_STATIC_TEMPLATE_SPECIALIZATION
-inline void qt_memrotate90_template<quint18, quint32>(const quint32 *src,
- int srcWidth, int srcHeight, int srcStride,
- quint18 *dest, int dstStride)
-{
-#if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD
- qt_memrotate90_cachedRead<quint18,quint32>(src, srcWidth, srcHeight,
- srcStride, dest, dstStride);
-#elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
- qt_memrotate90_cachedWrite<quint18,quint32>(src, srcWidth, srcHeight,
- srcStride, dest, dstStride);
-#elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING
- // packed algorithm not implemented
- qt_memrotate90_cachedRead<quint18,quint32>(src, srcWidth, srcHeight,
- srcStride, dest, dstStride);
-#elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
- // packed algorithm not implemented
- qt_memrotate90_tiled_unpacked<quint18,quint32>(src, srcWidth, srcHeight,
- srcStride, dest, dstStride);
-#endif
-}
-
-#define QT_IMPL_MEMROTATE(srctype, desttype) \
-Q_GUI_EXPORT void qt_memrotate90(const srctype *src, int w, int h, int sstride, \
- desttype *dest, int dstride) \
+#define QT_IMPL_MEMROTATE(type) \
+Q_GUI_EXPORT void qt_memrotate90(const type *src, int w, int h, int sstride, \
+ type *dest, int dstride) \
{ \
qt_memrotate90_template(src, w, h, sstride, dest, dstride); \
} \
-Q_GUI_EXPORT void qt_memrotate180(const srctype *src, int w, int h, int sstride, \
- desttype *dest, int dstride) \
+Q_GUI_EXPORT void qt_memrotate180(const type *src, int w, int h, int sstride, \
+ type *dest, int dstride) \
{ \
qt_memrotate180_template(src, w, h, sstride, dest, dstride); \
} \
-Q_GUI_EXPORT void qt_memrotate270(const srctype *src, int w, int h, int sstride, \
- desttype *dest, int dstride) \
+Q_GUI_EXPORT void qt_memrotate270(const type *src, int w, int h, int sstride, \
+ type *dest, int dstride) \
{ \
qt_memrotate270_template(src, w, h, sstride, dest, dstride); \
}
-#define QT_IMPL_SIMPLE_MEMROTATE(srctype, desttype) \
-Q_GUI_EXPORT void qt_memrotate90(const srctype *src, int w, int h, int sstride, \
- desttype *dest, int dstride) \
+#define QT_IMPL_SIMPLE_MEMROTATE(type) \
+Q_GUI_EXPORT void qt_memrotate90(const type *src, int w, int h, int sstride, \
+ type *dest, int dstride) \
{ \
- qt_memrotate90_tiled_unpacked<desttype,srctype>(src, w, h, sstride, dest, dstride); \
+ qt_memrotate90_tiled_unpacked<type>(src, w, h, sstride, dest, dstride); \
} \
-Q_GUI_EXPORT void qt_memrotate180(const srctype *src, int w, int h, int sstride, \
- desttype *dest, int dstride) \
+Q_GUI_EXPORT void qt_memrotate180(const type *src, int w, int h, int sstride, \
+ type *dest, int dstride) \
{ \
qt_memrotate180_template(src, w, h, sstride, dest, dstride); \
} \
-Q_GUI_EXPORT void qt_memrotate270(const srctype *src, int w, int h, int sstride, \
- desttype *dest, int dstride) \
+Q_GUI_EXPORT void qt_memrotate270(const type *src, int w, int h, int sstride, \
+ type *dest, int dstride) \
{ \
- qt_memrotate270_tiled_unpacked<desttype,srctype>(src, w, h, sstride, dest, dstride); \
+ qt_memrotate270_tiled_unpacked<type>(src, w, h, sstride, dest, dstride); \
}
-QT_IMPL_MEMROTATE(quint32, quint32)
-QT_IMPL_MEMROTATE(quint32, quint16)
-QT_IMPL_MEMROTATE(quint16, quint32)
-QT_IMPL_MEMROTATE(quint16, quint16)
-QT_IMPL_MEMROTATE(quint24, quint24)
-QT_IMPL_MEMROTATE(quint32, quint24)
-QT_IMPL_MEMROTATE(quint32, quint18)
-QT_IMPL_MEMROTATE(quint32, quint8)
-QT_IMPL_MEMROTATE(quint16, quint8)
-QT_IMPL_MEMROTATE(qrgb444, quint8)
-QT_IMPL_MEMROTATE(quint8, quint8)
-
-#if defined(QT_QWS_ROTATE_BGR)
-QT_IMPL_SIMPLE_MEMROTATE(quint16, qbgr565)
-QT_IMPL_SIMPLE_MEMROTATE(quint32, qbgr565)
-QT_IMPL_SIMPLE_MEMROTATE(qrgb555, qbgr555)
-QT_IMPL_SIMPLE_MEMROTATE(quint32, qbgr555)
-#endif
-
-#ifdef QT_QWS_DEPTH_GENERIC
-QT_IMPL_MEMROTATE(quint32, qrgb_generic16)
-QT_IMPL_MEMROTATE(quint16, qrgb_generic16)
-#endif
-
-struct qrgb_gl_rgba
-{
-public:
- inline qrgb_gl_rgba(quint32 v) {
- if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
- data = ((v << 16) & 0xff0000) | ((v >> 16) & 0xff) | (v & 0xff00ff00);
- else
- data = (v << 8) | ((v >> 24) & 0xff);
- }
-
- inline operator quint32() const { return data; }
-
-private:
- quint32 data;
-} Q_PACKED;
-
-void Q_GUI_EXPORT qt_memrotate90_gl(const quint32 *src, int srcWidth, int srcHeight, int srcStride,
- quint32 *dest, int dstStride)
-{
- qt_memrotate90_template(src, srcWidth, srcHeight, srcStride, reinterpret_cast<qrgb_gl_rgba *>(dest), dstStride);
-}
+QT_IMPL_MEMROTATE(quint32)
+QT_IMPL_MEMROTATE(quint16)
+QT_IMPL_MEMROTATE(quint24)
+QT_IMPL_MEMROTATE(quint8)
void qt_memrotate90_16(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
{
diff --git a/src/gui/painting/qmemrotate_p.h b/src/gui/painting/qmemrotate_p.h
index 4c4bc94767..a72310e330 100644
--- a/src/gui/painting/qmemrotate_p.h
+++ b/src/gui/painting/qmemrotate_p.h
@@ -70,37 +70,15 @@ QT_BEGIN_NAMESPACE
#endif
#endif
-#define QT_DECL_MEMROTATE(srctype, desttype) \
- void Q_GUI_EXPORT qt_memrotate90(const srctype*, int, int, int, desttype*, int); \
- void Q_GUI_EXPORT qt_memrotate180(const srctype*, int, int, int, desttype*, int); \
- void Q_GUI_EXPORT qt_memrotate270(const srctype*, int, int, int, desttype*, int)
+#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); \
+ void Q_GUI_EXPORT qt_memrotate270(const type*, int, int, int, type*, int)
-void Q_GUI_EXPORT qt_memrotate90(const quint32*, int, int, int, quint32*, int);
-void Q_GUI_EXPORT qt_memrotate180(const quint32*, int, int, int, quint32*, int);
-void Q_GUI_EXPORT qt_memrotate270(const quint32*, int, int, int, quint32*, int);
-
-QT_DECL_MEMROTATE(quint32, quint16);
-QT_DECL_MEMROTATE(quint16, quint32);
-QT_DECL_MEMROTATE(quint16, quint16);
-QT_DECL_MEMROTATE(quint24, quint24);
-QT_DECL_MEMROTATE(quint32, quint24);
-QT_DECL_MEMROTATE(quint32, quint18);
-QT_DECL_MEMROTATE(quint32, quint8);
-QT_DECL_MEMROTATE(quint16, quint8);
-QT_DECL_MEMROTATE(qrgb444, quint8);
-QT_DECL_MEMROTATE(quint8, quint8);
-
-#ifdef QT_QWS_ROTATE_BGR
-QT_DECL_MEMROTATE(quint16, qbgr565);
-QT_DECL_MEMROTATE(quint32, qbgr565);
-QT_DECL_MEMROTATE(qrgb555, qbgr555);
-QT_DECL_MEMROTATE(quint32, qbgr555);
-#endif
-
-#ifdef QT_QWS_DEPTH_GENERIC
-QT_DECL_MEMROTATE(quint32, qrgb_generic16);
-QT_DECL_MEMROTATE(quint16, qrgb_generic16);
-#endif
+QT_DECL_MEMROTATE(quint32);
+QT_DECL_MEMROTATE(quint16);
+QT_DECL_MEMROTATE(quint24);
+QT_DECL_MEMROTATE(quint8);
#undef QT_DECL_MEMROTATE