6#include <private/qimage_p.h>
7#include <private/qsimd_p.h>
9#ifdef QT_COMPILER_SUPPORTS_SSSE3
16Q_GUI_EXPORT
void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst,
const uchar *src,
int len)
21 ALIGNMENT_PROLOGUE_16BYTES(dst, i, len) {
22 dst[i] = qRgb(src[0], src[1], src[2]);
27 const __m128i shuffleMask = _mm_set_epi8(
char(0xff), 9, 10, 11,
char(0xff), 6, 7, 8,
char(0xff), 3, 4, 5,
char(0xff), 0, 1, 2);
30 const __m128i shuffleMaskEnd = _mm_set_epi8(
char(0xff), 13, 14, 15,
char(0xff), 10, 11, 12,
char(0xff), 7, 8, 9,
char(0xff), 4, 5, 6);
33 const __m128i alphaMask = _mm_set1_epi32(0xff000000);
35 const __m128i *inVectorPtr = (
const __m128i *)src;
36 __m128i *dstVectorPtr = (__m128i *)(dst + i);
38 for (; i < (len - 15); i += 16) {
40
41
42
43
44
45
46
47
48
49 __m128i firstSrcVector = _mm_lddqu_si128(inVectorPtr);
50 __m128i outputVector = _mm_shuffle_epi8(firstSrcVector, shuffleMask);
51 _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask));
57 __m128i secondSrcVector = _mm_lddqu_si128(inVectorPtr);
58 __m128i srcVector = _mm_alignr_epi8(secondSrcVector, firstSrcVector, 12);
59 outputVector = _mm_shuffle_epi8(srcVector, shuffleMask);
60 _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask));
63 firstSrcVector = secondSrcVector;
66 secondSrcVector = _mm_lddqu_si128(inVectorPtr);
67 srcVector = _mm_alignr_epi8(secondSrcVector, firstSrcVector, 8);
68 outputVector = _mm_shuffle_epi8(srcVector, shuffleMask);
69 _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask));
75 outputVector = _mm_shuffle_epi8(secondSrcVector, shuffleMaskEnd);
76 _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask));
79 src = (
const uchar *)inVectorPtr;
81 SIMD_EPILOGUE(i, len, 15) {
82 dst[i] = qRgb(src[0], src[1], src[2]);
87void convert_RGB888_to_RGB32_ssse3(QImageData *dest,
const QImageData *src, Qt::ImageConversionFlags)
89 Q_ASSERT(src->format == QImage::Format_RGB888 || src->format == QImage::Format_BGR888);
90 if (src->format == QImage::Format_BGR888)
91 Q_ASSERT(dest->format == QImage::Format_RGBX8888 || dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied);
93 Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied);
94 Q_ASSERT(src->width == dest->width);
95 Q_ASSERT(src->height == dest->height);
97 const uchar *src_data = (uchar *) src->data;
98 quint32 *dest_data = (quint32 *) dest->data;
100 for (
int i = 0; i < src->height; ++i) {
101 qt_convert_rgb888_to_rgb32_ssse3(dest_data, src_data, src->width);
102 src_data += src->bytes_per_line;
103 dest_data = (quint32 *)((uchar*)dest_data + dest->bytes_per_line);