diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/image/qimage.cpp | 4 | ||||
-rw-r--r-- | src/gui/image/qimage_conversions.cpp | 537 | ||||
-rw-r--r-- | src/gui/image/qimage_sse2.cpp | 7 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 62 |
4 files changed, 187 insertions, 423 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 86e739dd4f..57e7c9a7ab 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -4595,7 +4595,9 @@ bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFla InPlace_Image_Converter converter = *converterPtr; if (converter) return converter(this, flags); - else if (format > QImage::Format_Indexed8 && newFormat > QImage::Format_Indexed8) + else if (format > QImage::Format_Indexed8 && newFormat > QImage::Format_Indexed8 && !qimage_converter_map[format][newFormat]) + // Convert inplace generic, but only if there are no direct converters, + // any direct ones are probably better even if not inplace. return convert_generic_inplace(this, newFormat, flags); else return false; diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index ff729981c0..a4c02bbbbe 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include <private/qdrawhelper_p.h> +#include <private/qdrawingprimitive_sse2_p.h> #include <private/qguiapplication_p.h> #include <private/qsimd_p.h> @@ -100,9 +101,37 @@ void qGamma_correct_back_to_linear_cs(QImage *image) Internal routines for converting image depth. *****************************************************************************/ -// Cannot be used with indexed formats. +// 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 QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = 0xff000000 | qUnpremultiply(src[i]); + return buffer; +} + +#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) +QT_FUNCTION_TARGET(SSE4_1) +static const uint *QT_FASTCALL convertRGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = 0xff000000 | qUnpremultiply_sse4(src[i]); + return buffer; +} +#endif + +static const uint *QT_FASTCALL convertRGB32ToARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = 0xff000000 |src[i]; + return buffer; +} + void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { + // Cannot be used with indexed formats. Q_ASSERT(dest->format > QImage::Format_Indexed8); Q_ASSERT(src->format > QImage::Format_Indexed8); const int buffer_size = 2048; @@ -112,16 +141,33 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio const uchar *srcData = src->data; uchar *destData = dest->data; - FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp]; - StorePixelsFunc store = qStorePixels[destLayout->bpp]; + const FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp]; + const StorePixelsFunc store = qStorePixels[destLayout->bpp]; + ConvertFunc convertToARGB32PM = srcLayout->convertToARGB32PM; + ConvertFunc convertFromARGB32PM = destLayout->convertFromARGB32PM; + if (srcLayout->alphaWidth == 0 && destLayout->convertFromRGB32) { + // If the source doesn't have an alpha channel, we can use the faster convertFromRGB32 method. + convertFromARGB32PM = destLayout->convertFromRGB32; + } else { + if (src->format == QImage::Format_RGB32) + convertToARGB32PM = convertRGB32ToARGB32PM; + if (dest->format == QImage::Format_RGB32) { +#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) + if (qCpuHasFeature(SSE4_1)) + convertFromARGB32PM = convertRGB32FromARGB32PM_sse4; + else +#endif + convertFromARGB32PM = convertRGB32FromARGB32PM; + } + } 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); + ptr = convertToARGB32PM(buffer, ptr, l, srcLayout, 0); + ptr = convertFromARGB32PM(buffer, ptr, l, destLayout, 0); store(destData, ptr, x, l); x += l; } @@ -130,9 +176,9 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio } } -// Cannot be used with indexed formats or between formats with different pixel depths. bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::ImageConversionFlags) { + // Cannot be used with indexed formats or between formats with different pixel depths. Q_ASSERT(dst_format > QImage::Format_Indexed8); Q_ASSERT(data->format > QImage::Format_Indexed8); if (data->depth != qt_depthForFormat(dst_format)) @@ -142,19 +188,35 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im uint buffer[buffer_size]; const QPixelLayout *srcLayout = &qPixelLayouts[data->format]; const QPixelLayout *destLayout = &qPixelLayouts[dst_format]; - uchar *srcData = data->data; - FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp]; - StorePixelsFunc store = qStorePixels[destLayout->bpp]; + const FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp]; + const StorePixelsFunc store = qStorePixels[destLayout->bpp]; + ConvertFunc convertToARGB32PM = srcLayout->convertToARGB32PM; + ConvertFunc convertFromARGB32PM = destLayout->convertFromARGB32PM; + if (srcLayout->alphaWidth == 0 && destLayout->convertFromRGB32) { + // If the source doesn't have an alpha channel, we can use the faster convertFromRGB32 method. + convertFromARGB32PM = destLayout->convertFromRGB32; + } else { + if (data->format == QImage::Format_RGB32) + convertToARGB32PM = convertRGB32ToARGB32PM; + if (dst_format == QImage::Format_RGB32) { +#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) + if (qCpuHasFeature(SSE4_1)) + convertFromARGB32PM = convertRGB32FromARGB32PM_sse4; + else +#endif + convertFromARGB32PM = convertRGB32FromARGB32PM; + } + } for (int y = 0; y < data->height; ++y) { int x = 0; while (x < data->width) { int l = qMin(data->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); + ptr = convertToARGB32PM(buffer, ptr, l, srcLayout, 0); + ptr = convertFromARGB32PM(buffer, ptr, l, destLayout, 0); // 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); @@ -230,27 +292,6 @@ static void convert_ARGB_to_ARGB_PM_sse4(QImageData *dest, const QImageData *src extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags); -#ifndef __SSE2__ -static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags) -{ - Q_ASSERT(data->format == QImage::Format_ARGB32); - - const int pad = (data->bytes_per_line >> 2) - data->width; - QRgb *rgb_data = (QRgb *) data->data; - - for (int i = 0; i < data->height; ++i) { - const QRgb *end = rgb_data + data->width; - while (rgb_data < end) { - *rgb_data = qPremultiply(*rgb_data); - ++rgb_data; - } - rgb_data += pad; - } - data->format = QImage::Format_ARGB32_Premultiplied; - return true; -} -#endif - static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { Q_ASSERT(src->format == QImage::Format_ARGB32); @@ -321,39 +362,6 @@ static bool convert_ARGB_to_RGBA_inplace(QImageData *data, Qt::ImageConversionFl return true; } -static inline void convert_ARGB_to_RGBA_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_ARGB32); - Q_ASSERT(dest->format == QImage::Format_RGBA8888_Premultiplied); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 2) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const quint32 *src_data = (quint32 *) src->data; - quint32 *dest_data = (quint32 *) dest->data; - - for (int i = 0; i < src->height; ++i) { - const quint32 *end = src_data + src->width; - while (src_data < end) { - *dest_data = ARGB2RGBA(qPremultiply(*src_data)); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - -#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) && !defined(__SSE4_1__) -QT_FUNCTION_TARGET(SSE4_1) -static void convert_ARGB_to_RGBA_PM_sse4(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags) -{ - // Twice as fast autovectorized due to SSE4.1 PMULLD instructions. - convert_ARGB_to_RGBA_PM(dest, src, flags); -} -#endif - static void convert_RGBA_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { Q_ASSERT(src->format == QImage::Format_RGBX8888 || src->format == QImage::Format_RGBA8888 || src->format == QImage::Format_RGBA8888_Premultiplied); @@ -378,70 +386,24 @@ static void convert_RGBA_to_ARGB(QImageData *dest, const QImageData *src, Qt::Im } } +template<QImage::Format DestFormat> static bool convert_RGBA_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFlags) { Q_ASSERT(data->format == QImage::Format_RGBX8888 || data->format == QImage::Format_RGBA8888 || data->format == QImage::Format_RGBA8888_Premultiplied); const int pad = (data->bytes_per_line >> 2) - data->width; QRgb *rgb_data = (QRgb *) data->data; + Q_CONSTEXPR uint mask = (DestFormat == QImage::Format_RGB32) ? 0xff000000 : 0; for (int i = 0; i < data->height; ++i) { const QRgb *end = rgb_data + data->width; while (rgb_data < end) { - *rgb_data = RGBA2ARGB(*rgb_data); - ++rgb_data; - } - rgb_data += pad; - } - if (data->format == QImage::Format_RGBA8888_Premultiplied) - data->format = QImage::Format_ARGB32_Premultiplied; - else if (data->format == QImage::Format_RGBX8888) - data->format = QImage::Format_RGB32; - else - data->format = QImage::Format_ARGB32; - return true; -} - -static void convert_RGBA_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_RGBA8888); - Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 2) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const quint32 *src_data = (quint32 *) src->data; - quint32 *dest_data = (quint32 *) dest->data; - - for (int i = 0; i < src->height; ++i) { - const quint32 *end = src_data + src->width; - while (src_data < end) { - *dest_data = qPremultiply(RGBA2ARGB(*src_data)); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - -static bool convert_RGBA_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags) -{ - Q_ASSERT(data->format == QImage::Format_RGBA8888); - - const int pad = (data->bytes_per_line >> 2) - data->width; - QRgb *rgb_data = (QRgb *) data->data; - - for (int i = 0; i < data->height; ++i) { - const QRgb *end = rgb_data + data->width; - while (rgb_data < end) { - *rgb_data = qPremultiply(RGBA2ARGB(*rgb_data)); + *rgb_data = mask | RGBA2ARGB(*rgb_data); ++rgb_data; } rgb_data += pad; } - data->format = QImage::Format_ARGB32_Premultiplied; + data->format = DestFormat; return true; } @@ -497,106 +459,6 @@ static void convert_RGB30_to_RGB(QImageData *dest, const QImageData *src, Qt::Im } } -template<QtPixelOrder PixelOrder> -static void convert_A2RGB30_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_A2RGB30_Premultiplied || src->format == QImage::Format_A2BGR30_Premultiplied); - Q_ASSERT(dest->format == QImage::Format_RGB32); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 2) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const quint32 *src_data = (quint32 *) src->data; - quint32 *dest_data = (quint32 *) dest->data; - - for (int i = 0; i < src->height; ++i) { - const quint32 *end = src_data + src->width; - while (src_data < end) { - *dest_data = 0xff000000 | qUnpremultiply(qConvertA2rgb30ToArgb32<PixelOrder>(*src_data)); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - -template<QtPixelOrder PixelOrder> -static void convert_ARGB_PM_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied); - Q_ASSERT(dest->format == QImage::Format_BGR30 || dest->format == QImage::Format_RGB30); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 2) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const quint32 *src_data = (quint32 *) src->data; - quint32 *dest_data = (quint32 *) dest->data; - - for (int i = 0; i < src->height; ++i) { - const quint32 *end = src_data + src->width; - while (src_data < end) { - *dest_data = qConvertRgb32ToRgb30<PixelOrder>(qUnpremultiply(*src_data)); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - -template<QtPixelOrder PixelOrder> -static void convert_ARGB_to_A2RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied); - Q_ASSERT(dest->format == QImage::Format_A2BGR30_Premultiplied || dest->format == QImage::Format_A2RGB30_Premultiplied); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 2) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const quint32 *src_data = (quint32 *) src->data; - quint32 *dest_data = (quint32 *) dest->data; - - for (int i = 0; i < src->height; ++i) { - const quint32 *end = src_data + src->width; - while (src_data < end) { - *dest_data = qConvertArgb32ToA2rgb30<PixelOrder>(*src_data); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - -template<QtPixelOrder PixelOrder> -static void convert_A2RGB30_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_A2BGR30_Premultiplied || src->format == QImage::Format_A2RGB30_Premultiplied); - Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 2) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const quint32 *src_data = (quint32 *) src->data; - quint32 *dest_data = (quint32 *) dest->data; - - for (int i = 0; i < src->height; ++i) { - const quint32 *end = src_data + src->width; - while (src_data < end) { - *dest_data = qConvertA2rgb30ToArgb32<PixelOrder>(*src_data); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - static inline uint qUnpremultiplyRgb30(uint rgb30) { const uint a = rgb30 >> 30; @@ -916,7 +778,7 @@ static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFl } } -static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src) { Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied || src->format == QImage::Format_RGBA8888_Premultiplied); Q_ASSERT(dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_RGBA8888); @@ -940,78 +802,6 @@ static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt: } } -static void convert_ARGB_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied || src->format == QImage::Format_RGBA8888_Premultiplied); - Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_RGBX8888); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 2) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const QRgb *src_data = (QRgb *) src->data; - QRgb *dest_data = (QRgb *) dest->data; - - for (int i = 0; i < src->height; ++i) { - const QRgb *end = src_data + src->width; - while (src_data < end) { - *dest_data = 0xff000000 | qUnpremultiply(*src_data); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - -static void convert_ARGB_PM_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied); - Q_ASSERT(dest->format == QImage::Format_RGBX8888); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 2) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const QRgb *src_data = (QRgb *) src->data; - QRgb *dest_data = (QRgb *) dest->data; - - for (int i = 0; i < src->height; ++i) { - const QRgb *end = src_data + src->width; - while (src_data < end) { - *dest_data = ARGB2RGBA(0xff000000 | qUnpremultiply(*src_data)); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - -static void convert_ARGB_PM_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied); - Q_ASSERT(dest->format == QImage::Format_RGBA8888); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 2) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const QRgb *src_data = (QRgb *) src->data; - QRgb *dest_data = (QRgb *) dest->data; - - for (int i = 0; i < src->height; ++i) { - const QRgb *end = src_data + src->width; - while (src_data < end) { - *dest_data = ARGB2RGBA(qUnpremultiply(*src_data)); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - static void convert_RGBA_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { Q_ASSERT(src->format == QImage::Format_RGBA8888 || src->format == QImage::Format_RGBX8888); @@ -1036,78 +826,6 @@ static void convert_RGBA_to_RGB(QImageData *dest, const QImageData *src, Qt::Ima } } -static void convert_RGB_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_RGB32); - Q_ASSERT(dest->format == QImage::Format_RGBX8888 || dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 2) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const uint *src_data = (const uint *)src->data; - uint *dest_data = (uint *)dest->data; - - for (int i = 0; i < src->height; ++i) { - const uint *end = src_data + src->width; - while (src_data < end) { - *dest_data = ARGB2RGBA(*src_data | 0xff000000); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - -static void convert_RGBA_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_RGBA8888_Premultiplied); - Q_ASSERT(dest->format == QImage::Format_ARGB32); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 2) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const QRgb *src_data = (QRgb *) src->data; - QRgb *dest_data = (QRgb *) dest->data; - - for (int i = 0; i < src->height; ++i) { - const QRgb *end = src_data + src->width; - while (src_data < end) { - *dest_data = qUnpremultiply(RGBA2ARGB(*src_data)); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - -static void convert_RGBA_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_RGBA8888_Premultiplied); - Q_ASSERT(dest->format == QImage::Format_RGB32); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 2) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const QRgb *src_data = (QRgb *) src->data; - QRgb *dest_data = (QRgb *) dest->data; - - for (int i = 0; i < src->height; ++i) { - const QRgb *end = src_data + src->width; - while (src_data < end) { - *dest_data = 0xff000000 | qUnpremultiply(RGBA2ARGB(*src_data)); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - static void swap_bit_order(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB); @@ -1151,6 +869,26 @@ static void mask_alpha_converter(QImageData *dest, const QImageData *src, Qt::Im } } +template<QImage::Format DestFormat> +static bool mask_alpha_converter_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_RGB32 || DestFormat == QImage::Format_RGB32); + + const int pad = (data->bytes_per_line >> 2) - data->width; + QRgb *rgb_data = (QRgb *) data->data; + + for (int i = 0; i < data->height; ++i) { + const QRgb *end = rgb_data + data->width; + while (rgb_data < end) { + *rgb_data = *rgb_data | 0xff000000; + ++rgb_data; + } + rgb_data += pad; + } + data->format = DestFormat; + return true; +} + static void mask_alpha_converter_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags) { #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN @@ -1475,7 +1213,7 @@ static void convert_X_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageC static void convert_ARGB_PM_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags) { QScopedPointer<QImageData> tmp(QImageData::create(QSize(src->width, src->height), QImage::Format_ARGB32)); - convert_ARGB_PM_to_ARGB(tmp.data(), src, flags); + convert_ARGB_PM_to_ARGB(tmp.data(), src); dither_to_Mono(dst, tmp.data(), flags, false); } @@ -1755,7 +1493,7 @@ static void convert_RGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt:: static void convert_ARGB_PM_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags) { QScopedPointer<QImageData> tmp(QImageData::create(QSize(src->width, src->height), QImage::Format_ARGB32)); - convert_ARGB_PM_to_ARGB(tmp.data(), src, flags); + convert_ARGB_PM_to_ARGB(tmp.data(), src); convert_RGB_to_Indexed8(dst, tmp.data(), flags); } @@ -2113,9 +1851,9 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - convert_RGB_to_RGBA, - convert_RGB_to_RGBA, - convert_RGB_to_RGBA, + 0, + 0, + 0, convert_RGB_to_RGB30<PixelOrderBGR>, convert_RGB_to_RGB30<PixelOrderBGR>, convert_RGB_to_RGB30<PixelOrderRGB>, @@ -2142,7 +1880,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, convert_ARGB_to_RGBx, convert_ARGB_to_RGBA, - convert_ARGB_to_RGBA_PM, + 0, convert_RGB_to_RGB30<PixelOrderBGR>, 0, convert_RGB_to_RGB30<PixelOrderRGB>, @@ -2155,8 +1893,6 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_ARGB_PM_to_Mono, convert_ARGB_PM_to_Mono, convert_ARGB_PM_to_Indexed8, - convert_ARGB_PM_to_RGB, - convert_ARGB_PM_to_ARGB, 0, 0, 0, @@ -2167,13 +1903,15 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - convert_ARGB_PM_to_RGBx, - convert_ARGB_PM_to_RGBA, + 0, + 0, + 0, + 0, convert_ARGB_to_RGBA, - convert_ARGB_PM_to_RGB30<PixelOrderBGR>, - convert_ARGB_to_A2RGB30<PixelOrderBGR>, - convert_ARGB_PM_to_RGB30<PixelOrderRGB>, - convert_ARGB_to_A2RGB30<PixelOrderRGB>, + 0, + 0, + 0, + 0, 0, 0 }, // Format_ARGB32_Premultiplied @@ -2402,7 +2140,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, convert_RGBA_to_RGB, convert_RGBA_to_ARGB, - convert_RGBA_to_ARGB_PM, + 0, 0, 0, 0, @@ -2428,11 +2166,9 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - convert_RGBA_PM_to_RGB, - convert_RGBA_PM_to_ARGB, - convert_RGBA_to_ARGB, 0, 0, + convert_RGBA_to_ARGB, 0, 0, 0, @@ -2440,15 +2176,10 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - convert_ARGB_PM_to_RGB, - convert_ARGB_PM_to_ARGB, 0, -#else 0, 0, 0, -#endif 0, 0, 0, 0, 0, 0 }, // Format_RGBA8888_Premultiplied @@ -2483,9 +2214,9 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - convert_A2RGB30_PM_to_RGB<PixelOrderBGR>, 0, - convert_A2RGB30_to_ARGB<PixelOrderBGR>, + 0, + 0, 0, 0, 0, @@ -2535,9 +2266,9 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - convert_A2RGB30_PM_to_RGB<PixelOrderRGB>, 0, - convert_A2RGB30_to_ARGB<PixelOrderRGB>, + 0, + 0, 0, 0, 0, @@ -2639,8 +2370,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, - 0, + mask_alpha_converter_inplace<QImage::Format_ARGB32>, + mask_alpha_converter_inplace<QImage::Format_ARGB32_Premultiplied>, convert_RGB_to_RGB16_inplace, 0, 0, @@ -2652,19 +2383,20 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, + 0, 0, 0, 0, 0, 0 }, // Format_RGB32 { 0, 0, 0, 0, - 0, + mask_alpha_converter_inplace<QImage::Format_RGB32>, 0, #ifdef __SSE2__ convert_ARGB_to_ARGB_PM_inplace_sse2, #else - convert_ARGB_to_ARGB_PM_inplace, + 0, #endif 0, 0, @@ -2677,7 +2409,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, convert_ARGB_to_RGBA_inplace, - 0, 0, 0, 0, 0, 0, 0 + 0, + 0, 0, 0, 0, 0, 0 }, // Format_ARGB32 { 0, @@ -2733,9 +2466,9 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - convert_RGBA_to_ARGB_inplace, - convert_RGBA_to_ARGB_inplace, - convert_RGBA_to_ARGB_inplace, + convert_RGBA_to_ARGB_inplace<QImage::Format_RGB32>, + convert_RGBA_to_ARGB_inplace<QImage::Format_ARGB32>, + convert_RGBA_to_ARGB_inplace<QImage::Format_ARGB32_Premultiplied>, 0, 0, 0, @@ -2755,9 +2488,9 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, + convert_RGBA_to_ARGB_inplace<QImage::Format_RGB32>, + convert_RGBA_to_ARGB_inplace<QImage::Format_ARGB32>, 0, - convert_RGBA_to_ARGB_inplace, - convert_RGBA_to_ARGB_PM_inplace, 0, 0, 0, @@ -2768,8 +2501,13 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN && __SSE2__ 0, + convert_ARGB_to_ARGB_PM_inplace_sse2, +#else 0, + 0, +#endif 0, 0, 0, 0, 0, 0 }, // Format_RGBA8888 { @@ -2779,7 +2517,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - convert_RGBA_to_ARGB_inplace, + convert_RGBA_to_ARGB_inplace<QImage::Format_ARGB32_Premultiplied>, 0, 0, 0, @@ -2967,7 +2705,6 @@ void qInitImageConversions() if (qCpuHasFeature(SSE4_1)) { qimage_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_sse4; qimage_converter_map[QImage::Format_RGBA8888][QImage::Format_RGBA8888_Premultiplied] = convert_ARGB_to_ARGB_PM_sse4; - qimage_converter_map[QImage::Format_ARGB32][QImage::Format_RGBA8888_Premultiplied] = convert_ARGB_to_RGBA_PM_sse4; } #endif diff --git a/src/gui/image/qimage_sse2.cpp b/src/gui/image/qimage_sse2.cpp index 6424e67cfc..4a719d4c26 100644 --- a/src/gui/image/qimage_sse2.cpp +++ b/src/gui/image/qimage_sse2.cpp @@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags) { - Q_ASSERT(data->format == QImage::Format_ARGB32); + Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_RGBA8888); // extra pixels on each line const int spare = data->width & 3; @@ -92,7 +92,10 @@ bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionF d = reinterpret_cast<__m128i*>(p+pad); } - data->format = QImage::Format_ARGB32_Premultiplied; + if (data->format == QImage::Format_ARGB32) + data->format = QImage::Format_ARGB32_Premultiplied; + else + data->format = QImage::Format_RGBA8888_Premultiplied; return true; } diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 26ddef75e1..f461dfef06 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -265,6 +265,29 @@ static const uint *QT_FASTCALL convertRGBFromRGB32(uint *buffer, const uint *src } template<QImage::Format Format> +static const uint *QT_FASTCALL convertARGBPMFromRGB32(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + Q_CONSTEXPR uint alphaMask = ((1 << alphaWidth<Format>()) - 1); + Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1); + Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1); + Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1); + + Q_CONSTEXPR uchar redRightShift = 24 - redWidth<Format>(); + Q_CONSTEXPR uchar greenRightShift = 16 - greenWidth<Format>(); + Q_CONSTEXPR uchar blueRightShift = 8 - blueWidth<Format>(); + + for (int i = 0; i < count; ++i) { + Q_CONSTEXPR uint alpha = (0xff & alphaMask) << alphaShift<Format>(); + const uint red = ((src[i] >> redRightShift) & redMask) << redShift<Format>(); + const uint green = ((src[i] >> greenRightShift) & greenMask) << greenShift<Format>(); + const uint blue = ((src[i] >> blueRightShift) & blueMask) << blueShift<Format>(); + buffer[i] = alpha | red | green | blue; + } + return buffer; +} + +template<QImage::Format Format> static const uint *QT_FASTCALL convertARGBPMFromARGB32PM(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *) { @@ -312,7 +335,7 @@ template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixe true, bitsPerPixel<Format>(), convertARGBPMToARGB32PM<Format>, convertARGBPMFromARGB32PM<Format>, - 0 + convertARGBPMFromRGB32<Format> }; } @@ -444,12 +467,11 @@ static const uint *QT_FASTCALL convertFromRGB32(uint *buffer, const uint *src, i Q_ASSERT(layout->redWidth <= 8); Q_ASSERT(layout->greenWidth <= 8); Q_ASSERT(layout->blueWidth <= 8); - Q_ASSERT(layout->alphaWidth == 0); - Q_ASSERT(!layout->premultiplied); 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; @@ -459,7 +481,8 @@ static const uint *QT_FASTCALL convertFromRGB32(uint *buffer, const uint *src, 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; - buffer[i] = red | green | blue; + uint alpha = (0xff & alphaMask) << layout->alphaShift; + buffer[i] = red | green | blue | alpha; } return buffer; } @@ -814,10 +837,10 @@ QPixelLayout qPixelLayouts[QImage::NImageFormats] = { { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1LSB, convertIndexedToARGB32PM, 0, 0 }, // Format_MonoLSB { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertIndexedToARGB32PM, 0, 0 }, // Format_Indexed8 // Technically using convertPassThrough to convert from ARGB32PM to RGB32 is wrong, - // but everywhere this generic conversion would be wrong is currently overloaed. + // 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 }, // Format_RGB32 - { 8, 16, 8, 8, 8, 0, 8, 24, false, QPixelLayout::BPP32, convertARGB32ToARGB32PM, convertARGB32FromARGB32PM, 0 }, // Format_ARGB32 - { 8, 16, 8, 8, 8, 0, 8, 24, true, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, 0 }, // Format_ARGB32_Premultiplied + { 8, 16, 8, 8, 8, 0, 8, 24, false, QPixelLayout::BPP32, convertARGB32ToARGB32PM, convertARGB32FromARGB32PM, convertPassThrough }, // Format_ARGB32 + { 8, 16, 8, 8, 8, 0, 8, 24, true, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, convertPassThrough }, // Format_ARGB32_Premultiplied #ifdef Q_COMPILER_CONSTEXPR pixelLayoutRGB<QImage::Format_RGB16>(), pixelLayoutARGBPM<QImage::Format_ARGB8565_Premultiplied>(), @@ -830,28 +853,28 @@ QPixelLayout qPixelLayouts[QImage::NImageFormats] = { pixelLayoutARGBPM<QImage::Format_ARGB4444_Premultiplied>(), #else { 5, 11, 6, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertRGB16ToRGB32, convertRGB16FromARGB32PM, convertRGB16FromRGB32 }, // Format_RGB16 - { 5, 19, 6, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, 0 }, // Format_ARGB8565_Premultiplied + { 5, 19, 6, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, convertFromRGB32 }, // Format_ARGB8565_Premultiplied { 6, 12, 6, 6, 6, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB666 - { 6, 12, 6, 6, 6, 0, 6, 18, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, 0 }, // Format_ARGB6666_Premultiplied + { 6, 12, 6, 6, 6, 0, 6, 18, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, convertFromRGB32 }, // Format_ARGB6666_Premultiplied { 5, 10, 5, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB555 - { 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, 0 }, // Format_ARGB8555_Premultiplied + { 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, convertFromRGB32 }, // Format_ARGB8555_Premultiplied { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB888 { 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB444 - { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM, 0 }, // Format_ARGB4444_Premultiplied + { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM, convertFromRGB32 }, // Format_ARGB4444_Premultiplied #endif #if Q_BYTE_ORDER == Q_BIG_ENDIAN { 8, 24, 8, 16, 8, 8, 0, 0, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBX8888 - { 8, 24, 8, 16, 8, 8, 8, 0, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, 0 }, // Format_RGBA8888 - { 8, 24, 8, 16, 8, 8, 8, 0, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, 0 }, // Format_RGBA8888_Premultiplied + { 8, 24, 8, 16, 8, 8, 8, 0, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBA8888 + { 8, 24, 8, 16, 8, 8, 8, 0, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, convertRGBXFromRGB32}, // Format_RGBA8888_Premultiplied #else { 8, 0, 8, 8, 8, 16, 0, 24, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBX8888 - { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, 0 }, // Format_RGBA8888 (ABGR32) - { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, 0 }, // Format_RGBA8888_Premultiplied + { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBA8888 (ABGR32) + { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBA8888_Premultiplied #endif { 10, 20, 10, 10, 10, 0, 0, 30, false, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderBGR>, convertRGB30FromARGB32PM<PixelOrderBGR>, convertRGB30FromRGB32<PixelOrderBGR> }, // Format_BGR30 - { 10, 20, 10, 10, 10, 0, 2, 30, true, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderBGR>, convertA2RGB30PMFromARGB32PM<PixelOrderBGR>, 0 }, // Format_A2BGR30_Premultiplied + { 10, 20, 10, 10, 10, 0, 2, 30, true, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderBGR>, convertA2RGB30PMFromARGB32PM<PixelOrderBGR>, convertRGB30FromRGB32<PixelOrderBGR> }, // Format_A2BGR30_Premultiplied { 10, 0, 10, 10, 10, 20, 0, 30, false, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderRGB>, convertRGB30FromARGB32PM<PixelOrderRGB>, convertRGB30FromRGB32<PixelOrderRGB> }, // Format_RGB30 - { 10, 0, 10, 10, 10, 20, 2, 30, true, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderRGB>, convertA2RGB30PMFromARGB32PM<PixelOrderRGB>, 0 }, // Format_A2RGB30_Premultiplied + { 10, 0, 10, 10, 10, 20, 2, 30, true, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderRGB>, convertA2RGB30PMFromARGB32PM<PixelOrderRGB>, convertRGB30FromRGB32<PixelOrderRGB> }, // Format_A2RGB30_Premultiplied { 0, 0, 0, 0, 0, 0, 8, 0, false, QPixelLayout::BPP8, convertAlpha8ToRGB32, convertAlpha8FromARGB32PM, 0 }, // Format_Alpha8 { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertGrayscale8ToRGB32, convertGrayscale8FromARGB32PM, convertGrayscale8FromRGB32 } // Format_Grayscale8 }; @@ -1074,10 +1097,9 @@ static void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer, int x, int y, con while (length) { int l = qMin(length, buffer_size); const uint *ptr = 0; - if (layout->convertFromRGB32) { - Q_ASSERT(!layout->premultiplied && !layout->alphaWidth); + if (!layout->premultiplied && !layout->alphaWidth) ptr = layout->convertFromRGB32(buf, buffer, l, layout, 0); - } else + else ptr = layout->convertFromARGB32PM(buf, buffer, l, layout, 0); store(dest, ptr, x, l); length -= l; |