Merge drawhelper convert-from and store

Avoids using an intermediate buffer on store and simplifies the code.

Change-Id: I2dc4e735eb770f90dc99fe0f513b4df3b35ee793
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
bb10
Allan Sandfeld Jensen 2018-04-04 17:45:28 +02:00
parent 6a39e49a6c
commit 648ee7aa02
10 changed files with 598 additions and 686 deletions

View File

@ -2303,8 +2303,7 @@ QRgb QImage::pixel(int x, int y) const
}
const QPixelLayout *layout = &qPixelLayouts[d->format];
uint result;
const uint *ptr = qFetchPixels[layout->bpp](&result, s, x, 1);
return *layout->convertToARGB32PM(&result, ptr, 1, 0, 0);
return *layout->fetchToARGB32PM(&result, s, x, 1, nullptr, nullptr);
}
/*!
@ -2405,9 +2404,7 @@ void QImage::setPixel(int x, int y, uint index_or_rgb)
}
const QPixelLayout *layout = &qPixelLayouts[d->format];
uint result;
const uint *ptr = layout->convertFromARGB32PM(&result, &index_or_rgb, 1, 0, 0);
qStorePixels[layout->bpp](s, ptr, x, 1);
layout->storeFromARGB32PM(s, &index_or_rgb, x, 1, nullptr, nullptr);
}
/*!
@ -2584,14 +2581,13 @@ bool QImage::allGray() const
uint buffer[BufferSize];
const QPixelLayout *layout = &qPixelLayouts[d->format];
FetchPixelsFunc fetch = qFetchPixels[layout->bpp];
const auto fetch = layout->fetchToARGB32PM;
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, BufferSize);
const uint *ptr = fetch(buffer, b, x, l);
ptr = layout->convertToARGB32PM(buffer, ptr, l, 0, 0);
const uint *ptr = fetch(buffer, b, x, l, nullptr, nullptr);
for (int i = 0; i < l; ++i) {
if (!qIsGray(ptr[i]))
return false;
@ -3209,9 +3205,7 @@ void QImage::mirrored_inplace(bool horizontal, bool vertical)
inline void rgbSwapped_generic(int width, int height, const QImage *src, QImage *dst, const QPixelLayout* layout)
{
FetchPixelsFunc fetch = qFetchPixels[layout->bpp];
StorePixelsFunc store = qStorePixels[layout->bpp];
RbSwapFunc func = layout->rbSwap;
const RbSwapFunc func = layout->rbSwap;
if (!func) {
qWarning("Trying to rb-swap an image format where it doesn't make sense");
if (src != dst)
@ -3219,19 +3213,10 @@ inline void rgbSwapped_generic(int width, int height, const QImage *src, QImage
return;
}
uint buffer[BufferSize];
for (int i = 0; i < height; ++i) {
uchar *q = dst->scanLine(i);
const uchar *p = src->constScanLine(i);
int x = 0;
while (x < width) {
int l = qMin(width - x, BufferSize);
const uint *ptr = fetch(buffer, p, x, l);
ptr = func(buffer, ptr, l);
if (q != (const uchar *)ptr)
store(q, ptr, x, l);
x += l;
}
func(q, p, width);
}
}

View File

@ -118,26 +118,35 @@ void qGamma_correct_back_to_linear_cs(QImage *image)
Internal routines for converting image depth.
*****************************************************************************/
// The drawhelper conversions from/to RGB32 are passthroughs which is not always correct for general image conversion.
static const uint *QT_FASTCALL convertRGB32FromARGB32PM(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
// The drawhelper conversions from/to RGB32 are passthroughs which is not always correct for general image conversion
static void QT_FASTCALL storeRGB32FromARGB32PM(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
uint *d = reinterpret_cast<uint *>(dest) + index;
for (int i = 0; i < count; ++i)
buffer[i] = 0xff000000 | qUnpremultiply(src[i]);
return buffer;
d[i] = 0xff000000 | qUnpremultiply(src[i]);
}
static const uint *QT_FASTCALL maskRGB32(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
static void QT_FASTCALL storeRGB32FromARGB32(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
uint *d = reinterpret_cast<uint *>(dest) + index;
for (int i = 0; i < count; ++i)
buffer[i] = 0xff000000 |src[i];
d[i] = 0xff000000 | src[i];
}
static const uint *QT_FASTCALL fetchRGB32ToARGB32PM(uint *buffer, const uchar *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
const uint *s = reinterpret_cast<const uint *>(src) + index;
for (int i = 0; i < count; ++i)
buffer[i] = 0xff000000 | s[i];
return buffer;
}
#ifdef QT_COMPILER_SUPPORTS_SSE4_1
extern const uint *QT_FASTCALL convertRGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *);
extern void QT_FASTCALL storeRGB32FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
#endif
void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags)
@ -152,34 +161,32 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
const uchar *srcData = src->data;
uchar *destData = dest->data;
const FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp];
const StorePixelsFunc store = qStorePixels[destLayout->bpp];
ConvertFunc convertToARGB32PM = srcLayout->convertToARGB32PM;
ConvertFunc convertFromARGB32PM = destLayout->convertFromARGB32PM;
if (!srcLayout->hasAlphaChannel && destLayout->convertFromRGB32) {
// If the source doesn't have an alpha channel, we can use the faster convertFromRGB32 method.
convertFromARGB32PM = destLayout->convertFromRGB32;
FetchAndConvertPixelsFunc fetch = srcLayout->fetchToARGB32PM;
ConvertAndStorePixelsFunc store = destLayout->storeFromARGB32PM;
if (!srcLayout->hasAlphaChannel && destLayout->storeFromRGB32) {
// If the source doesn't have an alpha channel, we can use the faster storeFromRGB32 method.
store = destLayout->storeFromRGB32;
} else {
// The drawhelpers do not mask the alpha value in RGB32, we want to here.
if (src->format == QImage::Format_RGB32)
convertToARGB32PM = maskRGB32;
fetch = fetchRGB32ToARGB32PM;
if (dest->format == QImage::Format_RGB32) {
#ifdef QT_COMPILER_SUPPORTS_SSE4_1
if (qCpuHasFeature(SSE4_1))
convertFromARGB32PM = convertRGB32FromARGB32PM_sse4;
store = storeRGB32FromARGB32PM_sse4;
else
#endif
convertFromARGB32PM = convertRGB32FromARGB32PM;
store = storeRGB32FromARGB32PM;
}
}
if ((src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888) &&
!destLayout->hasAlphaChannel && destLayout->convertFromRGB32) {
!destLayout->hasAlphaChannel && destLayout->storeFromRGB32) {
// Avoid unnecessary premultiply and unpremultiply when converting from unpremultiplied src format.
convertToARGB32PM = qPixelLayouts[src->format + 1].convertToARGB32PM;
fetch = qPixelLayouts[src->format + 1].fetchToARGB32PM;
if (dest->format == QImage::Format_RGB32)
convertFromARGB32PM = maskRGB32;
store = storeRGB32FromARGB32;
else
convertFromARGB32PM = destLayout->convertFromRGB32;
store = destLayout->storeFromRGB32;
}
QDitherInfo dither;
QDitherInfo *ditherPtr = 0;
@ -196,11 +203,8 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
buffer = reinterpret_cast<uint *>(destData) + x;
else
l = qMin(l, BufferSize);
const uint *ptr = fetch(buffer, srcData, x, l);
ptr = convertToARGB32PM(buffer, ptr, l, 0, ditherPtr);
ptr = convertFromARGB32PM(buffer, ptr, l, 0, ditherPtr);
if (ptr != reinterpret_cast<uint *>(destData))
store(destData, ptr, x, l);
const uint *ptr = fetch(buffer, srcData, x, l, 0, ditherPtr);
store(destData, ptr, x, l, 0, ditherPtr);
x += l;
}
srcData += src->bytes_per_line;
@ -216,38 +220,37 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im
if (data->depth != qt_depthForFormat(dst_format))
return false;
uint buffer[BufferSize];
uint buf[BufferSize];
uint *buffer = buf;
const QPixelLayout *srcLayout = &qPixelLayouts[data->format];
const QPixelLayout *destLayout = &qPixelLayouts[dst_format];
uchar *srcData = data->data;
const FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp];
const StorePixelsFunc store = qStorePixels[destLayout->bpp];
ConvertFunc convertToARGB32PM = srcLayout->convertToARGB32PM;
ConvertFunc convertFromARGB32PM = destLayout->convertFromARGB32PM;
if (!srcLayout->hasAlphaChannel && destLayout->convertFromRGB32) {
// If the source doesn't have an alpha channel, we can use the faster convertFromRGB32 method.
convertFromARGB32PM = destLayout->convertFromRGB32;
FetchAndConvertPixelsFunc fetch = srcLayout->fetchToARGB32PM;
ConvertAndStorePixelsFunc store = destLayout->storeFromARGB32PM;
if (!srcLayout->hasAlphaChannel && destLayout->storeFromRGB32) {
// If the source doesn't have an alpha channel, we can use the faster storeFromRGB32 method.
store = destLayout->storeFromRGB32;
} else {
if (data->format == QImage::Format_RGB32)
convertToARGB32PM = maskRGB32;
fetch = fetchRGB32ToARGB32PM;
if (dst_format == QImage::Format_RGB32) {
#ifdef QT_COMPILER_SUPPORTS_SSE4_1
if (qCpuHasFeature(SSE4_1))
convertFromARGB32PM = convertRGB32FromARGB32PM_sse4;
store = storeRGB32FromARGB32PM_sse4;
else
#endif
convertFromARGB32PM = convertRGB32FromARGB32PM;
store = storeRGB32FromARGB32PM;
}
}
if ((data->format == QImage::Format_ARGB32 || data->format == QImage::Format_RGBA8888) &&
!destLayout->hasAlphaChannel && destLayout->convertFromRGB32) {
!destLayout->hasAlphaChannel && destLayout->storeFromRGB32) {
// Avoid unnecessary premultiply and unpremultiply when converting from unpremultiplied src format.
convertToARGB32PM = qPixelLayouts[data->format + 1].convertToARGB32PM;
if (dst_format == QImage::Format_RGB32)
convertFromARGB32PM = maskRGB32;
fetch = qPixelLayouts[data->format + 1].fetchToARGB32PM;
if (data->format == QImage::Format_RGB32)
store = storeRGB32FromARGB32;
else
convertFromARGB32PM = destLayout->convertFromRGB32;
store = destLayout->storeFromRGB32;
}
QDitherInfo dither;
QDitherInfo *ditherPtr = 0;
@ -259,13 +262,13 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im
int x = 0;
while (x < data->width) {
dither.x = x;
int l = qMin(data->width - x, BufferSize);
const uint *ptr = fetch(buffer, srcData, x, l);
ptr = convertToARGB32PM(buffer, ptr, l, 0, ditherPtr);
ptr = convertFromARGB32PM(buffer, ptr, l, 0, ditherPtr);
// The conversions might be passthrough and not use the buffer, in that case we are already done.
if (srcData != (const uchar*)ptr)
store(srcData, ptr, x, l);
int l = data->width - x;
if (destLayout->bpp == QPixelLayout::BPP32)
buffer = reinterpret_cast<uint *>(srcData) + x;
else
l = qMin(l, BufferSize);
const uint *ptr = fetch(buffer, srcData, x, l, nullptr, ditherPtr);
store(srcData, ptr, x, l, nullptr, ditherPtr);
x += l;
}
srcData += data->bytes_per_line;

View File

@ -47,12 +47,12 @@
QT_BEGIN_NAMESPACE
const uint *QT_FASTCALL convertRGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
void QT_FASTCALL storeRGB32FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
uint *d = reinterpret_cast<uint *>(dest) + index;
for (int i = 0; i < count; ++i)
buffer[i] = 0xff000000 | qUnpremultiply_sse4(src[i]);
return buffer;
d[i] = 0xff000000 | qUnpremultiply_sse4(src[i]);
}
void convert_ARGB_to_ARGB_PM_sse4(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)

View File

@ -150,13 +150,7 @@ void QBlittablePlatformPixmap::fill(const QColor &color)
m_alpha = true;
}
uint pixel = qPremultiply(color.rgba());
const QPixelLayout *layout = &qPixelLayouts[blittable()->lock()->format()];
Q_ASSERT(layout->convertFromARGB32PM);
layout->convertFromARGB32PM(&pixel, &pixel, 1, 0, 0);
//so premultiplied formats are supported and ARGB32 and RGB32
blittable()->lock()->fill(pixel);
blittable()->lock()->fill(color);
}
}

View File

@ -193,17 +193,12 @@ void QRasterPlatformPixmap::fill(const QColor &color)
if (alpha != 255) {
if (!image.hasAlphaChannel()) {
QImage::Format toFormat = qt_alphaVersionForPainting(image.format());
if (!image.isNull() && qt_depthForFormat(image.format()) == qt_depthForFormat(toFormat)) {
image.detach();
image.d->format = toFormat;
} else {
if (!image.reinterpretAsFormat(toFormat))
image = QImage(image.width(), image.height(), toFormat);
}
}
}
pixel = qPremultiply(color.rgba());
const QPixelLayout *layout = &qPixelLayouts[image.format()];
layout->convertFromARGB32PM(&pixel, &pixel, 1, 0, 0);
image.fill(color);
return;
} else if (image.format() == QImage::Format_Alpha8) {
pixel = qAlpha(color.rgba());
} else if (image.format() == QImage::Format_Grayscale8) {

File diff suppressed because it is too large Load Diff

View File

@ -1153,18 +1153,14 @@ static inline void convertARGBToARGB32PM_neon(uint *buffer, const uint *src, int
}
}
const uint *QT_FASTCALL convertARGB32ToARGB32PM_neon(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
void QT_FASTCALL convertARGB32ToARGB32PM_neon(uint *buffer, int count, const QVector<QRgb> *)
{
convertARGBToARGB32PM_neon<false>(buffer, src, count);
return buffer;
convertARGBToARGB32PM_neon<false>(buffer, buffer, count);
}
const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_neon(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
void QT_FASTCALL convertRGBA8888ToARGB32PM_neon(uint *buffer, int count, const QVector<QRgb> *)
{
convertARGBToARGB32PM_neon<true>(buffer, src, count);
return buffer;
convertARGBToARGB32PM_neon<true>(buffer, buffer, count);
}
#endif // Q_BYTE_ORDER == Q_LITTLE_ENDIAN

View File

@ -1227,11 +1227,15 @@ struct QDitherInfo {
int y;
};
typedef const uint *(QT_FASTCALL *ConvertFunc)(uint *buffer, const uint *src, int count,
const QVector<QRgb> *clut, QDitherInfo *dither);
typedef const uint *(QT_FASTCALL *FetchAndConvertPixelsFunc)(uint *buffer, const uchar *src, int index, int count,
const QVector<QRgb> *clut, QDitherInfo *dither);
typedef void (QT_FASTCALL *ConvertAndStorePixelsFunc)(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *clut, QDitherInfo *dither);
typedef void (QT_FASTCALL *ConvertFunc)(uint *buffer, int count, const QVector<QRgb> *clut);
typedef const QRgba64 *(QT_FASTCALL *ConvertFunc64)(QRgba64 *buffer, const uint *src, int count,
const QVector<QRgb> *clut, QDitherInfo *dither);
typedef const uint *(QT_FASTCALL *RbSwapFunc)(uint *buffer, const uint *src, int count);
typedef void (QT_FASTCALL *RbSwapFunc)(uchar *dst, const uchar *src, int count);
struct QPixelLayout
@ -1253,17 +1257,13 @@ struct QPixelLayout
BPP bpp;
RbSwapFunc rbSwap;
ConvertFunc convertToARGB32PM;
ConvertFunc convertFromARGB32PM;
ConvertFunc convertFromRGB32;
ConvertFunc64 convertToARGB64PM;
FetchAndConvertPixelsFunc fetchToARGB32PM;
ConvertAndStorePixelsFunc storeFromARGB32PM;
ConvertAndStorePixelsFunc storeFromRGB32;
};
typedef const uint *(QT_FASTCALL *FetchPixelsFunc)(uint *buffer, const uchar *src, int index, int count);
typedef void (QT_FASTCALL *StorePixelsFunc)(uchar *dest, const uint *src, int index, int count);
extern QPixelLayout qPixelLayouts[QImage::NImageFormats];
extern const FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount];
extern StorePixelsFunc qStorePixels[QPixelLayout::BPPCount];
extern MemRotateFunc qMemRotateFunctions[QPixelLayout::BPPCount][3];

View File

@ -93,59 +93,55 @@ static inline void convertARGBToARGB32PM_sse4(uint *buffer, const uint *src, int
}
}
const uint *QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
void QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, int count, const QVector<QRgb> *)
{
convertARGBToARGB32PM_sse4<false>(buffer, src, count);
return buffer;
convertARGBToARGB32PM_sse4<false>(buffer, buffer, count);
}
const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
void QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer, int count, const QVector<QRgb> *)
{
convertARGBToARGB32PM_sse4<true>(buffer, src, count);
return buffer;
convertARGBToARGB32PM_sse4<true>(buffer, buffer, count);
}
const uint *QT_FASTCALL convertARGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
void QT_FASTCALL storeARGB32FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
uint *d = reinterpret_cast<uint *>(dest) + index;
for (int i = 0; i < count; ++i)
buffer[i] = qUnpremultiply_sse4(src[i]);
return buffer;
d[i] = qUnpremultiply_sse4(src[i]);
}
const uint *QT_FASTCALL convertRGBA8888FromARGB32PM_sse4(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
void QT_FASTCALL storeRGBA8888FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
uint *d = reinterpret_cast<uint *>(dest) + index;
for (int i = 0; i < count; ++i)
buffer[i] = ARGB2RGBA(qUnpremultiply_sse4(src[i]));
return buffer;
d[i] = ARGB2RGBA(qUnpremultiply_sse4(src[i]));
}
const uint *QT_FASTCALL convertRGBXFromARGB32PM_sse4(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
void QT_FASTCALL storeRGBXFromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
uint *d = reinterpret_cast<uint *>(dest) + index;
for (int i = 0; i < count; ++i)
buffer[i] = ARGB2RGBA(0xff000000 | qUnpremultiply_sse4(src[i]));
return buffer;
d[i] = ARGB2RGBA(0xff000000 | qUnpremultiply_sse4(src[i]));
}
template<QtPixelOrder PixelOrder>
const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
void QT_FASTCALL storeA2RGB30PMFromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
uint *d = reinterpret_cast<uint *>(dest) + index;
for (int i = 0; i < count; ++i)
buffer[i] = qConvertArgb32ToA2rgb30_sse4<PixelOrder>(src[i]);
return buffer;
d[i] = qConvertArgb32ToA2rgb30_sse4<PixelOrder>(src[i]);
}
template
const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4<PixelOrderBGR>(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *);
void QT_FASTCALL storeA2RGB30PMFromARGB32PM_sse4<PixelOrderBGR>(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
template
const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *);
void QT_FASTCALL storeA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
QT_END_NAMESPACE

View File

@ -167,61 +167,12 @@ void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl,
}
}
static inline void store_uint24_ssse3(uchar *dst, const uint *src, int len)
const uint *QT_FASTCALL fetchPixelsBPP24_ssse3(uint *buffer, const uchar *src, int index, int count)
{
int i = 0;
quint24 *dst24 = reinterpret_cast<quint24*>(dst);
// Align dst on 16 bytes
for (; i < len && (reinterpret_cast<quintptr>(dst24) & 0xf); ++i)
*dst24++ = quint24(*src++);
// Shuffle masks for first and second half of every output, all outputs are aligned so the shuffled ends are not used.
const __m128i shuffleMask1 = _mm_setr_epi8(char(0x80), char(0x80), char(0x80), char(0x80), 2, 1, 0, 6, 5, 4, 10, 9, 8, 14, 13, 12);
const __m128i shuffleMask2 = _mm_setr_epi8(2, 1, 0, 6, 5, 4, 10, 9, 8, 14, 13, 12, char(0x80), char(0x80), char(0x80), char(0x80));
const __m128i *inVectorPtr = (const __m128i *)src;
__m128i *dstVectorPtr = (__m128i *)dst24;
for (; i < (len - 15); i += 16) {
// Load four vectors, store three.
// Create each output vector by combining two shuffled input vectors.
__m128i srcVector1 = _mm_loadu_si128(inVectorPtr);
++inVectorPtr;
__m128i srcVector2 = _mm_loadu_si128(inVectorPtr);
++inVectorPtr;
__m128i outputVector1 = _mm_shuffle_epi8(srcVector1, shuffleMask1);
__m128i outputVector2 = _mm_shuffle_epi8(srcVector2, shuffleMask2);
__m128i outputVector = _mm_alignr_epi8(outputVector2, outputVector1, 4);
_mm_store_si128(dstVectorPtr, outputVector);
++dstVectorPtr;
srcVector1 = _mm_loadu_si128(inVectorPtr);
++inVectorPtr;
outputVector1 = _mm_shuffle_epi8(srcVector2, shuffleMask1);
outputVector2 = _mm_shuffle_epi8(srcVector1, shuffleMask2);
outputVector = _mm_alignr_epi8(outputVector2, outputVector1, 8);
_mm_store_si128(dstVectorPtr, outputVector);
++dstVectorPtr;
srcVector2 = _mm_loadu_si128(inVectorPtr);
++inVectorPtr;
outputVector1 = _mm_shuffle_epi8(srcVector1, shuffleMask1);
outputVector2 = _mm_shuffle_epi8(srcVector2, shuffleMask2);
outputVector = _mm_alignr_epi8(outputVector2, outputVector1, 12);
_mm_store_si128(dstVectorPtr, outputVector);
++dstVectorPtr;
}
dst24 = reinterpret_cast<quint24*>(dstVectorPtr);
src = reinterpret_cast<const uint*>(inVectorPtr);
SIMD_EPILOGUE(i, len, 15)
*dst24++ = quint24(*src++);
}
void QT_FASTCALL storePixelsBPP24_ssse3(uchar *dest, const uint *src, int index, int count)
{
store_uint24_ssse3(dest + index * 3, src, count);
const quint24 *s = reinterpret_cast<const quint24 *>(src);
for (int i = 0; i < count; ++i)
buffer[i] = s[index + i];
return buffer;
}
extern void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len);