diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 469ae8b97e..e1cac2011d 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -3209,13 +3209,15 @@ void QImage::mirrored_inplace(bool horizontal, bool vertical) inline void rgbSwapped_generic(int width, int height, const QImage *src, QImage *dst, const QPixelLayout* layout) { - 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); + RbSwapFunc func = layout->rbSwap; + if (!func) { + qWarning("Trying to rb-swap an image format where it doesn't make sense"); + if (src != dst) + *dst = *src; + return; + } uint buffer[BufferSize]; for (int i = 0; i < height; ++i) { @@ -3225,14 +3227,9 @@ inline void rgbSwapped_generic(int width, int height, const QImage *src, QImage while (x < width) { int l = qMin(width - x, BufferSize); 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); + ptr = func(buffer, ptr, l); + if (q != (const uchar *)ptr) + store(q, ptr, x, l); x += l; } } @@ -3319,23 +3316,6 @@ QImage QImage::rgbSwapped_helper() const } } break; - case Format_BGR30: - case Format_A2BGR30_Premultiplied: - case Format_RGB30: - case Format_A2RGB30_Premultiplied: - res = QImage(d->width, d->height, d->format); - QIMAGE_SANITYCHECK_MEMORY(res); - for (int i = 0; i < d->height; i++) { - uint *q = (uint*)res.scanLine(i); - const uint *p = (const uint*)constScanLine(i); - const uint *end = p + d->width; - while (p < end) { - *q = qRgbSwapRgb30(*p); - p++; - q++; - } - } - break; default: res = QImage(d->width, d->height, d->format); rgbSwapped_generic(d->width, d->height, this, &res, &qPixelLayouts[d->format]); diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 9a8cbf43c9..39d97f4bd9 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -156,7 +156,7 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio const StorePixelsFunc store = qStorePixels[destLayout->bpp]; ConvertFunc convertToARGB32PM = srcLayout->convertToARGB32PM; ConvertFunc convertFromARGB32PM = destLayout->convertFromARGB32PM; - if (srcLayout->alphaWidth == 0 && destLayout->convertFromRGB32) { + if (!srcLayout->hasAlphaChannel && destLayout->convertFromRGB32) { // If the source doesn't have an alpha channel, we can use the faster convertFromRGB32 method. convertFromARGB32PM = destLayout->convertFromRGB32; } else { @@ -173,7 +173,7 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio } } if ((src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888) && - destLayout->alphaWidth == 0 && destLayout->convertFromRGB32) { + !destLayout->hasAlphaChannel && destLayout->convertFromRGB32) { // Avoid unnecessary premultiply and unpremultiply when converting from unpremultiplied src format. convertToARGB32PM = qPixelLayouts[src->format + 1].convertToARGB32PM; if (dest->format == QImage::Format_RGB32) @@ -225,7 +225,7 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im const StorePixelsFunc store = qStorePixels[destLayout->bpp]; ConvertFunc convertToARGB32PM = srcLayout->convertToARGB32PM; ConvertFunc convertFromARGB32PM = destLayout->convertFromARGB32PM; - if (srcLayout->alphaWidth == 0 && destLayout->convertFromRGB32) { + if (!srcLayout->hasAlphaChannel && destLayout->convertFromRGB32) { // If the source doesn't have an alpha channel, we can use the faster convertFromRGB32 method. convertFromARGB32PM = destLayout->convertFromRGB32; } else { @@ -241,7 +241,7 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im } } if ((data->format == QImage::Format_ARGB32 || data->format == QImage::Format_RGBA8888) && - destLayout->alphaWidth == 0 && destLayout->convertFromRGB32) { + !destLayout->hasAlphaChannel && destLayout->convertFromRGB32) { // Avoid unnecessary premultiply and unpremultiply when converting from unpremultiplied src format. convertToARGB32PM = qPixelLayouts[data->format + 1].convertToARGB32PM; if (dst_format == QImage::Format_RGB32) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 3b115daf86..9db182e1a9 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -91,6 +91,10 @@ template<> Q_DECL_CONSTEXPR uint redWidth template<> Q_DECL_CONSTEXPR uint redWidth() { return 5; } template<> Q_DECL_CONSTEXPR uint redWidth() { return 5; } template<> Q_DECL_CONSTEXPR uint redWidth() { return 6; } +template<> Q_DECL_CONSTEXPR uint redWidth() { return 8; } +template<> Q_DECL_CONSTEXPR uint redWidth() { return 8; } +template<> Q_DECL_CONSTEXPR uint redWidth() { return 8; } + template<> Q_DECL_CONSTEXPR uint redShift() { return 11; } template<> Q_DECL_CONSTEXPR uint redShift() { return 8; } template<> Q_DECL_CONSTEXPR uint redShift() { return 10; } @@ -100,6 +104,15 @@ template<> Q_DECL_CONSTEXPR uint redShift template<> Q_DECL_CONSTEXPR uint redShift() { return 18; } template<> Q_DECL_CONSTEXPR uint redShift() { return 19; } template<> Q_DECL_CONSTEXPR uint redShift() { return 12; } +#if Q_BYTE_ORDER == Q_BIG_ENDIAN +template<> Q_DECL_CONSTEXPR uint redShift() { return 24; } +template<> Q_DECL_CONSTEXPR uint redShift() { return 24; } +template<> Q_DECL_CONSTEXPR uint redShift() { return 24; } +#else +template<> Q_DECL_CONSTEXPR uint redShift() { return 0; } +template<> Q_DECL_CONSTEXPR uint redShift() { return 0; } +template<> Q_DECL_CONSTEXPR uint redShift() { return 0; } +#endif template<> Q_DECL_CONSTEXPR uint greenWidth() { return 6; } template<> Q_DECL_CONSTEXPR uint greenWidth() { return 4; } template<> Q_DECL_CONSTEXPR uint greenWidth() { return 5; } @@ -109,6 +122,10 @@ template<> Q_DECL_CONSTEXPR uint greenWidth Q_DECL_CONSTEXPR uint greenWidth() { return 5; } template<> Q_DECL_CONSTEXPR uint greenWidth() { return 6; } template<> Q_DECL_CONSTEXPR uint greenWidth() { return 6; } +template<> Q_DECL_CONSTEXPR uint greenWidth() { return 8; } +template<> Q_DECL_CONSTEXPR uint greenWidth() { return 8; } +template<> Q_DECL_CONSTEXPR uint greenWidth() { return 8; } + template<> Q_DECL_CONSTEXPR uint greenShift() { return 5; } template<> Q_DECL_CONSTEXPR uint greenShift() { return 4; } template<> Q_DECL_CONSTEXPR uint greenShift() { return 5; } @@ -118,6 +135,15 @@ template<> Q_DECL_CONSTEXPR uint greenShift Q_DECL_CONSTEXPR uint greenShift() { return 13; } template<> Q_DECL_CONSTEXPR uint greenShift() { return 13; } template<> Q_DECL_CONSTEXPR uint greenShift() { return 6; } +#if Q_BYTE_ORDER == Q_BIG_ENDIAN +template<> Q_DECL_CONSTEXPR uint greenShift() { return 16; } +template<> Q_DECL_CONSTEXPR uint greenShift() { return 16; } +template<> Q_DECL_CONSTEXPR uint greenShift() { return 16; } +#else +template<> Q_DECL_CONSTEXPR uint greenShift() { return 8; } +template<> Q_DECL_CONSTEXPR uint greenShift() { return 8; } +template<> Q_DECL_CONSTEXPR uint greenShift() { return 8; } +#endif template<> Q_DECL_CONSTEXPR uint blueWidth() { return 5; } template<> Q_DECL_CONSTEXPR uint blueWidth() { return 4; } template<> Q_DECL_CONSTEXPR uint blueWidth() { return 5; } @@ -127,6 +153,10 @@ template<> Q_DECL_CONSTEXPR uint blueWidth Q_DECL_CONSTEXPR uint blueWidth() { return 5; } template<> Q_DECL_CONSTEXPR uint blueWidth() { return 5; } template<> Q_DECL_CONSTEXPR uint blueWidth() { return 6; } +template<> Q_DECL_CONSTEXPR uint blueWidth() { return 8; } +template<> Q_DECL_CONSTEXPR uint blueWidth() { return 8; } +template<> Q_DECL_CONSTEXPR uint blueWidth() { return 8; } + template<> Q_DECL_CONSTEXPR uint blueShift() { return 0; } template<> Q_DECL_CONSTEXPR uint blueShift() { return 0; } template<> Q_DECL_CONSTEXPR uint blueShift() { return 0; } @@ -136,6 +166,15 @@ template<> Q_DECL_CONSTEXPR uint blueShift Q_DECL_CONSTEXPR uint blueShift() { return 8; } template<> Q_DECL_CONSTEXPR uint blueShift() { return 8; } template<> Q_DECL_CONSTEXPR uint blueShift() { return 0; } +#if Q_BYTE_ORDER == Q_BIG_ENDIAN +template<> Q_DECL_CONSTEXPR uint blueShift() { return 8; } +template<> Q_DECL_CONSTEXPR uint blueShift() { return 8; } +template<> Q_DECL_CONSTEXPR uint blueShift() { return 8; } +#else +template<> Q_DECL_CONSTEXPR uint blueShift() { return 16; } +template<> Q_DECL_CONSTEXPR uint blueShift() { return 16; } +template<> Q_DECL_CONSTEXPR uint blueShift() { return 16; } +#endif template<> Q_DECL_CONSTEXPR uint alphaWidth() { return 0; } template<> Q_DECL_CONSTEXPR uint alphaWidth() { return 0; } template<> Q_DECL_CONSTEXPR uint alphaWidth() { return 0; } @@ -145,6 +184,10 @@ template<> Q_DECL_CONSTEXPR uint alphaWidth Q_DECL_CONSTEXPR uint alphaWidth() { return 8; } template<> Q_DECL_CONSTEXPR uint alphaWidth() { return 8; } template<> Q_DECL_CONSTEXPR uint alphaWidth() { return 6; } +template<> Q_DECL_CONSTEXPR uint alphaWidth() { return 0; } +template<> Q_DECL_CONSTEXPR uint alphaWidth() { return 8; } +template<> Q_DECL_CONSTEXPR uint alphaWidth() { return 8; } + template<> Q_DECL_CONSTEXPR uint alphaShift() { return 0; } template<> Q_DECL_CONSTEXPR uint alphaShift() { return 0; } template<> Q_DECL_CONSTEXPR uint alphaShift() { return 0; } @@ -154,6 +197,15 @@ template<> Q_DECL_CONSTEXPR uint alphaShift Q_DECL_CONSTEXPR uint alphaShift() { return 0; } template<> Q_DECL_CONSTEXPR uint alphaShift() { return 0; } template<> Q_DECL_CONSTEXPR uint alphaShift() { return 18; } +#if Q_BYTE_ORDER == Q_BIG_ENDIAN +template<> Q_DECL_CONSTEXPR uint alphaShift() { return 0; } +template<> Q_DECL_CONSTEXPR uint alphaShift() { return 0; } +template<> Q_DECL_CONSTEXPR uint alphaShift() { return 0; } +#else +template<> Q_DECL_CONSTEXPR uint alphaShift() { return 24; } +template<> Q_DECL_CONSTEXPR uint alphaShift() { return 24; } +template<> Q_DECL_CONSTEXPR uint alphaShift() { return 24; } +#endif template Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel(); template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel() { return QPixelLayout::BPP16; } @@ -165,6 +217,9 @@ template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel() { return QPixelLayout::BPP24; } template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel() { return QPixelLayout::BPP24; } template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel() { return QPixelLayout::BPP24; } +template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel() { return QPixelLayout::BPP32; } +template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel() { return QPixelLayout::BPP32; } +template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel() { return QPixelLayout::BPP32; } template @@ -447,16 +502,68 @@ static const uint *QT_FASTCALL convertARGBPMFromARGB32PM(uint *buffer, const uin return buffer; } +template +static const uint *QT_FASTCALL rbSwap(uint *buffer, const uint *src, int count) +{ + Q_CONSTEXPR uchar aWidth = alphaWidth(); + Q_CONSTEXPR uchar aShift = alphaShift(); + Q_CONSTEXPR uchar rWidth = redWidth(); + Q_CONSTEXPR uchar rShift = redShift(); + Q_CONSTEXPR uchar gWidth = greenWidth(); + Q_CONSTEXPR uchar gShift = greenShift(); + Q_CONSTEXPR uchar bWidth = blueWidth(); + Q_CONSTEXPR uchar bShift = blueShift(); #ifdef Q_COMPILER_CONSTEXPR + Q_STATIC_ASSERT(rWidth == bWidth); +#endif + Q_CONSTEXPR uint redBlueMask = (1 << rWidth) - 1; + Q_CONSTEXPR uint alphaGreenMask = (((1 << aWidth) - 1) << aShift) + | (((1 << gWidth) - 1) << gShift); + + for (int i = 0; i < count; ++i) { + const uint c = src[i]; + const uint r = (c >> rShift) & redBlueMask; + const uint b = (c >> bShift) & redBlueMask; + buffer[i] = (c & alphaGreenMask) + | (r << bShift) + | (b << rShift); + } + return buffer; +} + +static const uint *QT_FASTCALL rbSwap_rgb32(uint *buffer, const uint *src, int count) +{ + for (int i = 0; i < count; ++i) { + const uint c = src[i]; + const uint ag = c & 0xff00ff00; + const uint rb = c & 0x00ff00ff; + buffer[i] = ag | (rb << 16) | (rb >> 16); + } + return buffer; +} + +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN +template<> +const uint *QT_FASTCALL rbSwap(uint *buffer, const uint *src, int count) +{ + return rbSwap_rgb32(buffer, src, count); +} +#endif + +static const uint *QT_FASTCALL rbSwap_rgb30(uint *buffer, const uint *src, int count) +{ + for (int i = 0; i < count; ++i) + buffer[i] = qRgbSwapRgb30(src[i]); + return buffer; +} template Q_DECL_CONSTEXPR static inline QPixelLayout pixelLayoutRGB() { return QPixelLayout{ - uchar(redWidth()), uchar(redShift()), - uchar(greenWidth()), uchar(greenShift()), - uchar(blueWidth()), uchar(blueShift()), - 0, 0, - false, bitsPerPixel(), + false, + false, + bitsPerPixel(), + rbSwap, convertToRGB32, convertRGBFromARGB32PM, convertRGBFromARGB32PM, @@ -467,11 +574,10 @@ template Q_DECL_CONSTEXPR static inline QPixelLayout pixe template Q_DECL_CONSTEXPR static inline QPixelLayout pixelLayoutARGBPM() { return QPixelLayout{ - uchar(redWidth()), uchar(redShift()), - uchar(greenWidth()), uchar(greenShift()), - uchar(blueWidth()), uchar(blueShift()), - uchar(alphaWidth()), uchar(alphaShift()), - true, bitsPerPixel(), + true, + true, + bitsPerPixel(), + rbSwap, convertARGBPMToARGB32PM, convertARGBPMFromARGB32PM, convertARGBPMFromARGB32PM, @@ -479,8 +585,6 @@ template Q_DECL_CONSTEXPR static inline QPixelLayout pixe }; } -#endif - // 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 QVector *clut, QDitherInfo *) @@ -950,16 +1054,15 @@ inline void QT_FASTCALL storePixels(uchar *dest, const uint // 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, 0, 0 }, // Format_Invalid - { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1MSB, convertIndexedToARGB32PM, 0, 0, convertIndexedToARGB64PM }, // Format_Mono - { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1LSB, convertIndexedToARGB32PM, 0, 0, convertIndexedToARGB64PM }, // Format_MonoLSB - { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertIndexedToARGB32PM, 0, 0, convertIndexedToARGB64PM }, // Format_Indexed8 + { false, false, QPixelLayout::BPPNone, nullptr, nullptr, nullptr, nullptr, nullptr }, // Format_Invalid + { false, false, QPixelLayout::BPP1MSB, nullptr, convertIndexedToARGB32PM, 0, 0, convertIndexedToARGB64PM }, // Format_Mono + { false, false, QPixelLayout::BPP1LSB, nullptr, convertIndexedToARGB32PM, 0, 0, convertIndexedToARGB64PM }, // Format_MonoLSB + { false, false, QPixelLayout::BPP8, nullptr, convertIndexedToARGB32PM, 0, 0, convertIndexedToARGB64PM }, // Format_Indexed8 // Technically using convertPassThrough to convert from ARGB32PM to RGB32 is wrong, // but everywhere this generic conversion would be wrong is currently overloaded. - { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, convertPassThrough, convertRGB32ToRGB64 }, // Format_RGB32 - { 8, 16, 8, 8, 8, 0, 8, 24, false, QPixelLayout::BPP32, convertARGB32ToARGB32PM, convertARGB32FromARGB32PM, convertPassThrough, convertARGB32ToARGB64PM }, // Format_ARGB32 - { 8, 16, 8, 8, 8, 0, 8, 24, true, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, convertPassThrough, convertARGB32PMToARGB64PM }, // Format_ARGB32_Premultiplied -#ifdef Q_COMPILER_CONSTEXPR + { false, false, QPixelLayout::BPP32, rbSwap_rgb32, convertPassThrough, convertPassThrough, convertPassThrough, convertRGB32ToRGB64 }, // Format_RGB32 + { true, false, QPixelLayout::BPP32, rbSwap_rgb32, convertARGB32ToARGB32PM, convertARGB32FromARGB32PM, convertPassThrough, convertARGB32ToARGB64PM }, // Format_ARGB32 + { true, true, QPixelLayout::BPP32, rbSwap_rgb32, convertPassThrough, convertPassThrough, convertPassThrough, convertARGB32PMToARGB64PM }, // Format_ARGB32_Premultiplied pixelLayoutRGB(), pixelLayoutARGBPM(), pixelLayoutRGB(), @@ -969,77 +1072,15 @@ QPixelLayout qPixelLayouts[QImage::NImageFormats] = { pixelLayoutRGB(), pixelLayoutRGB(), pixelLayoutARGBPM(), -#else - { 5, 11, 6, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, - convertToRGB32, - convertRGBFromARGB32PM, - convertRGBFromARGB32PM, - convertToRGB64, - }, - { 5, 19, 6, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, - convertARGBPMToARGB32PM, - convertARGBPMFromARGB32PM, - convertARGBPMFromARGB32PM, - convertARGBPMToARGB64PM, - }, - { 6, 12, 6, 6, 6, 0, 0, 0, false, QPixelLayout::BPP24, - convertToRGB32, - convertRGBFromARGB32PM, - convertRGBFromARGB32PM, - convertToRGB64, - }, - { 6, 12, 6, 6, 6, 0, 6, 18, true, QPixelLayout::BPP24, - convertARGBPMToARGB32PM, - convertARGBPMFromARGB32PM, - convertARGBPMFromARGB32PM, - convertARGBPMToARGB64PM, - }, - { 5, 10, 5, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, - convertToRGB32, - convertRGBFromARGB32PM, - convertRGBFromARGB32PM, - convertToRGB64, - }, - { 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, - convertARGBPMToARGB32PM, - convertARGBPMFromARGB32PM, - convertARGBPMFromARGB32PM, - convertARGBPMToARGB64PM, - }, - { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP24, - convertToRGB32, - convertRGBFromARGB32PM, - convertRGBFromARGB32PM, - convertToRGB64, - }, - { 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16, - convertToRGB32, - convertRGBFromARGB32PM, - convertRGBFromARGB32PM, - convertToRGB64, - }, - { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, - convertARGBPMToARGB32PM, - convertARGBPMFromARGB32PM, - convertARGBPMFromARGB32PM, - convertARGBPMToARGB64PM, - }, -#endif -#if Q_BYTE_ORDER == Q_BIG_ENDIAN - { 8, 24, 8, 16, 8, 8, 0, 0, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM }, // Format_RGBX8888 - { 8, 24, 8, 16, 8, 8, 8, 0, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, convertRGBXFromRGB32, convertRGBA8888ToARGB64PM }, // Format_RGBA8888 - { 8, 24, 8, 16, 8, 8, 8, 0, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM}, // Format_RGBA8888_Premultiplied -#else - { 8, 0, 8, 8, 8, 16, 0, 24, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM }, // Format_RGBX8888 - { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, convertRGBXFromRGB32, convertRGBA8888ToARGB64PM }, // Format_RGBA8888 (ABGR32) - { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM }, // Format_RGBA8888_Premultiplied -#endif - { 10, 20, 10, 10, 10, 0, 0, 30, false, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM, convertRGB30FromARGB32PM, convertRGB30FromRGB32, convertA2RGB30PMToARGB64PM }, // Format_BGR30 - { 10, 20, 10, 10, 10, 0, 2, 30, true, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM, convertA2RGB30PMFromARGB32PM, convertRGB30FromRGB32, convertA2RGB30PMToARGB64PM }, // Format_A2BGR30_Premultiplied - { 10, 0, 10, 10, 10, 20, 0, 30, false, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM, convertRGB30FromARGB32PM, convertRGB30FromRGB32, convertA2RGB30PMToARGB64PM }, // Format_RGB30 - { 10, 0, 10, 10, 10, 20, 2, 30, true, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM, convertA2RGB30PMFromARGB32PM, convertRGB30FromRGB32, convertA2RGB30PMToARGB64PM }, // Format_A2RGB30_Premultiplied - { 0, 0, 0, 0, 0, 0, 8, 0, true, QPixelLayout::BPP8, convertAlpha8ToRGB32, convertAlpha8FromARGB32PM, 0, convertAlpha8ToRGB64 }, // Format_Alpha8 - { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertGrayscale8ToRGB32, convertGrayscale8FromARGB32PM, convertGrayscale8FromRGB32, convertGrayscale8ToRGB64 } // Format_Grayscale8 + { false, false, QPixelLayout::BPP32, rbSwap, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM }, // Format_RGBX8888 + { true, false, QPixelLayout::BPP32, rbSwap, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, convertRGBXFromRGB32, convertRGBA8888ToARGB64PM }, // Format_RGBA8888 (ABGR32) + { true, true, QPixelLayout::BPP32, rbSwap, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM }, // Format_RGBA8888_Premultiplied + { false, false, QPixelLayout::BPP32, rbSwap_rgb30, convertA2RGB30PMToARGB32PM, convertRGB30FromARGB32PM, convertRGB30FromRGB32, convertA2RGB30PMToARGB64PM }, // Format_BGR30 + { true, true, QPixelLayout::BPP32, rbSwap_rgb30, convertA2RGB30PMToARGB32PM, convertA2RGB30PMFromARGB32PM, convertRGB30FromRGB32, convertA2RGB30PMToARGB64PM }, // Format_A2BGR30_Premultiplied + { false, false, QPixelLayout::BPP32, rbSwap_rgb30, convertA2RGB30PMToARGB32PM, convertRGB30FromARGB32PM, convertRGB30FromRGB32, convertA2RGB30PMToARGB64PM }, // Format_RGB30 + { true, true, QPixelLayout::BPP32, rbSwap_rgb30, convertA2RGB30PMToARGB32PM, convertA2RGB30PMFromARGB32PM, convertRGB30FromRGB32, convertA2RGB30PMToARGB64PM }, // Format_A2RGB30_Premultiplied + { true, true, QPixelLayout::BPP8, nullptr, convertAlpha8ToRGB32, convertAlpha8FromARGB32PM, 0, convertAlpha8ToRGB64 }, // Format_Alpha8 + { false, false, QPixelLayout::BPP8, nullptr, convertGrayscale8ToRGB32, convertGrayscale8FromARGB32PM, convertGrayscale8FromRGB32, convertGrayscale8ToRGB64 } // Format_Grayscale8 }; const FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount] = { @@ -1308,7 +1349,7 @@ static void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer, int x, int y, con while (length) { int l = qMin(length, BufferSize); const uint *ptr = 0; - if (!layout->premultiplied && !layout->alphaWidth) + if (!layout->premultiplied && !layout->hasAlphaChannel) ptr = layout->convertFromRGB32(buf, buffer, l, 0, 0); else ptr = layout->convertFromARGB32PM(buf, buffer, l, 0, 0); @@ -1336,7 +1377,7 @@ static void QT_FASTCALL destStore64(QRasterBuffer *rasterBuffer, int x, int y, c int l = qMin(length, BufferSize); const uint *ptr = 0; convertFromRgb64(buf, buffer, l); - if (!layout->premultiplied && !layout->alphaWidth) + if (!layout->premultiplied && !layout->hasAlphaChannel) ptr = layout->convertFromRGB32(buf, buf, l, 0, 0); else ptr = layout->convertFromARGB32PM(buf, buf, l, 0, 0); diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 4604e0f8af..4940026abb 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -1217,6 +1217,8 @@ typedef const uint *(QT_FASTCALL *ConvertFunc)(uint *buffer, const uint *src, in const QVector *clut, QDitherInfo *dither); typedef const QRgba64 *(QT_FASTCALL *ConvertFunc64)(QRgba64 *buffer, const uint *src, int count, const QVector *clut, QDitherInfo *dither); +typedef const uint *(QT_FASTCALL *RbSwapFunc)(uint *buffer, const uint *src, int count); + struct QPixelLayout { @@ -1232,17 +1234,10 @@ struct QPixelLayout BPPCount }; - // All numbers in bits. - uchar redWidth; - uchar redShift; - uchar greenWidth; - uchar greenShift; - uchar blueWidth; - uchar blueShift; - uchar alphaWidth; - uchar alphaShift; + bool hasAlphaChannel; bool premultiplied; BPP bpp; + RbSwapFunc rbSwap; ConvertFunc convertToARGB32PM; ConvertFunc convertFromARGB32PM; ConvertFunc convertFromRGB32;