diff options
Diffstat (limited to 'src/gui/image/qimage_conversions.cpp')
-rw-r--r-- | src/gui/image/qimage_conversions.cpp | 813 |
1 files changed, 568 insertions, 245 deletions
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index d981c43711..e1f66dceee 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -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 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) + d[i] = 0xff000000 | src[i]; } -static const uint *QT_FASTCALL maskRGB32(uint *buffer, const uint *src, int count, - const QVector<QRgb> *, QDitherInfo *) +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 |src[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) @@ -145,42 +154,39 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio // 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; - uint buf[buffer_size]; + uint buf[BufferSize]; uint *buffer = buf; const QPixelLayout *srcLayout = &qPixelLayouts[src->format]; const QPixelLayout *destLayout = &qPixelLayouts[dest->format]; 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->alphaWidth == 0 && 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->alphaWidth == 0 && destLayout->convertFromRGB32) { + if (srcLayout->hasAlphaChannel && !srcLayout->premultiplied && + !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,12 +202,9 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio if (destLayout->bpp == QPixelLayout::BPP32) buffer = reinterpret_cast<uint *>(destData) + x; else - l = qMin(l, buffer_size); - 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); + l = qMin(l, BufferSize); + const uint *ptr = fetch(buffer, srcData, x, l, 0, ditherPtr); + store(destData, ptr, x, l, 0, ditherPtr); x += l; } srcData += src->bytes_per_line; @@ -209,6 +212,26 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio } } +void convert_generic_to_rgb64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(dest->format == QImage::Format_RGBA64_Premultiplied); + Q_ASSERT(src->format > QImage::Format_Indexed8); + const QPixelLayout *srcLayout = &qPixelLayouts[src->format]; + const uchar *srcData = src->data; + uchar *destData = dest->data; + + const FetchAndConvertPixelsFunc64 fetch = srcLayout->fetchToRGBA64PM; + + for (int y = 0; y < src->height; ++y) { + const QRgba64 *ptr = fetch((QRgba64*)destData, srcData, 0, src->width, nullptr, nullptr); + if (ptr != (const QRgba64*)destData) { + memcpy(destData, ptr, dest->bytes_per_line); + } + srcData += src->bytes_per_line; + destData += dest->bytes_per_line; + } +} + bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::ImageConversionFlags flags) { // Cannot be used with indexed formats or between formats with different pixel depths. @@ -217,39 +240,39 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im if (data->depth != qt_depthForFormat(dst_format)) return false; - const int buffer_size = 2048; - uint buffer[buffer_size]; + 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->alphaWidth == 0 && destLayout->convertFromRGB32) { - // If the source doesn't have an alpha channel, we can use the faster convertFromRGB32 method. - convertFromARGB32PM = destLayout->convertFromRGB32; + Q_ASSERT(srcLayout->bpp == destLayout->bpp); + Q_ASSERT(srcLayout->bpp != QPixelLayout::BPP64); + 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->alphaWidth == 0 && destLayout->convertFromRGB32) { + if (srcLayout->hasAlphaChannel && !srcLayout->premultiplied && + !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; @@ -261,13 +284,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, buffer_size); - 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; @@ -281,20 +304,15 @@ static void convert_passthrough(QImageData *dest, const QImageData *src, Qt::Ima 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; + const int src_bpl = src->bytes_per_line; + const int dest_bpl = dest->bytes_per_line; + const uchar *src_data = src->data; + uchar *dest_data = dest->data; for (int i = 0; i < src->height; ++i) { - const quint32 *end = src_data + src->width; - while (src_data < end) { - *dest_data = *src_data; - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; + memcpy(dest_data, src_data, src_bpl); + src_data += src_bpl; + dest_data += dest_bpl; } } @@ -305,30 +323,6 @@ static bool convert_passthrough_inplace(QImageData *data, Qt::ImageConversionFla return true; } -static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888); - Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || 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 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 = qPremultiply(*src_data); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32(quint32 *dest_data, const uchar *src_data, int len) { int pixel = 0; @@ -431,33 +425,6 @@ static void convert_RGB888_to_RGB(QImageData *dest, const QImageData *src, Qt::I } } -#ifdef __SSE2__ -extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags); -#else -static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data,Qt::ImageConversionFlags) -{ - Q_ASSERT(data->format == QImage::Format_ARGB32 || 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(*rgb_data); - ++rgb_data; - } - rgb_data += pad; - } - - if (data->format == QImage::Format_ARGB32) - data->format = QImage::Format_ARGB32_Premultiplied; - else - data->format = QImage::Format_RGBA8888_Premultiplied; - return true; -} -#endif - static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { Q_ASSERT(src->format == QImage::Format_ARGB32); @@ -573,11 +540,12 @@ static bool convert_RGBA_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFl return true; } -template<QtPixelOrder PixelOrder> +template<QtPixelOrder PixelOrder, bool RGBA> static void convert_RGB_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { - Q_ASSERT(src->format == QImage::Format_RGB32 || src->format == QImage::Format_ARGB32); + Q_ASSERT(RGBA || src->format == QImage::Format_RGB32 || src->format == QImage::Format_ARGB32); + Q_ASSERT(!RGBA || src->format == QImage::Format_RGBX8888 || src->format == QImage::Format_RGBA8888); Q_ASSERT(dest->format == QImage::Format_BGR30 || dest->format == QImage::Format_RGB30); Q_ASSERT(src->width == dest->width); Q_ASSERT(src->height == dest->height); @@ -590,7 +558,10 @@ static void convert_RGB_to_RGB30(QImageData *dest, const QImageData *src, Qt::Im for (int i = 0; i < src->height; ++i) { const quint32 *end = src_data + src->width; while (src_data < end) { - *dest_data = qConvertRgb32ToRgb30<PixelOrder>(*src_data); + QRgb c = *src_data; + if (RGBA) + c = RGBA2ARGB(c); + *dest_data = qConvertRgb32ToRgb30<PixelOrder>(c); ++src_data; ++dest_data; } @@ -599,10 +570,11 @@ static void convert_RGB_to_RGB30(QImageData *dest, const QImageData *src, Qt::Im } } -template<QtPixelOrder PixelOrder> +template<QtPixelOrder PixelOrder, bool RGBA> static bool convert_RGB_to_RGB30_inplace(QImageData *data, Qt::ImageConversionFlags) { - Q_ASSERT(data->format == QImage::Format_RGB32 || data->format == QImage::Format_ARGB32); + Q_ASSERT(RGBA || (data->format == QImage::Format_RGB32 || data->format == QImage::Format_ARGB32)); + Q_ASSERT(!RGBA || (data->format == QImage::Format_RGBX8888 || data->format == QImage::Format_RGBA8888)); const int pad = (data->bytes_per_line >> 2) - data->width; QRgb *rgb_data = (QRgb *) data->data; @@ -610,7 +582,10 @@ static bool convert_RGB_to_RGB30_inplace(QImageData *data, Qt::ImageConversionFl for (int i = 0; i < data->height; ++i) { const QRgb *end = rgb_data + data->width; while (rgb_data < end) { - *rgb_data = qConvertRgb32ToRgb30<PixelOrder>(*rgb_data); + QRgb c = *rgb_data; + if (RGBA) + c = RGBA2ARGB(c); + *rgb_data = qConvertRgb32ToRgb30<PixelOrder>(c); ++rgb_data; } rgb_data += pad; @@ -771,11 +746,11 @@ static bool convert_BGR30_to_A2RGB30_inplace(QImageData *data, Qt::ImageConversi return true; } -template<QtPixelOrder PixelOrder> +template<QtPixelOrder PixelOrder, bool RGBA> static void convert_A2RGB30_PM_to_ARGB(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_ARGB32); + Q_ASSERT(RGBA ? dest->format == QImage::Format_RGBA8888 : dest->format == QImage::Format_ARGB32); Q_ASSERT(src->width == dest->width); Q_ASSERT(src->height == dest->height); @@ -788,6 +763,8 @@ static void convert_A2RGB30_PM_to_ARGB(QImageData *dest, const QImageData *src, const quint32 *end = src_data + src->width; while (src_data < end) { *dest_data = qConvertA2rgb30ToArgb32<PixelOrder>(qUnpremultiplyRgb30(*src_data)); + if (RGBA) + *dest_data = ARGB2RGBA(*dest_data); ++src_data; ++dest_data; } @@ -796,7 +773,7 @@ static void convert_A2RGB30_PM_to_ARGB(QImageData *dest, const QImageData *src, } } -template<QtPixelOrder PixelOrder> +template<QtPixelOrder PixelOrder, bool RGBA> static bool convert_A2RGB30_PM_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFlags) { Q_ASSERT(data->format == QImage::Format_A2RGB30_Premultiplied || data->format == QImage::Format_A2BGR30_Premultiplied); @@ -808,11 +785,16 @@ static bool convert_A2RGB30_PM_to_ARGB_inplace(QImageData *data, Qt::ImageConver const uint *end = rgb_data + data->width; while (rgb_data < end) { *rgb_data = qConvertA2rgb30ToArgb32<PixelOrder>(qUnpremultiplyRgb30(*rgb_data)); + if (RGBA) + *rgb_data = ARGB2RGBA(*rgb_data); ++rgb_data; } rgb_data += pad; } - data->format = QImage::Format_ARGB32; + if (RGBA) + data->format = QImage::Format_RGBA8888; + else + data->format = QImage::Format_ARGB32; return true; } @@ -1188,6 +1170,270 @@ static bool mask_alpha_converter_rgbx_inplace(QImageData *data, Qt::ImageConvers #endif } +template<bool RGBA> +static void convert_RGBA64_to_ARGB32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_RGBA64); + Q_ASSERT(RGBA || dest->format == QImage::Format_ARGB32); + Q_ASSERT(!RGBA || dest->format == QImage::Format_RGBA8888); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const uchar *srcData = src->data; + uchar *destData = dest->data; + + for (int i = 0; i < src->height; ++i) { + uint *d = reinterpret_cast<uint *>(destData); + const QRgba64 *s = reinterpret_cast<const QRgba64 *>(srcData); + qt_convertRGBA64ToARGB32<RGBA>(d, s, src->width); + srcData += src->bytes_per_line; + destData += dest->bytes_per_line; + } +} + +template<bool RGBA> +static void convert_RGBA64PM_to_ARGB32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied); + Q_ASSERT(RGBA || dest->format == QImage::Format_ARGB32); + Q_ASSERT(!RGBA || 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 >> 3) - src->width; + const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; + const QRgba64 *src_data = reinterpret_cast<const QRgba64 *>(src->data); + uint *dest_data = reinterpret_cast<uint *>(dest->data); + + for (int i = 0; i < src->height; ++i) { + const QRgba64 *end = src_data + src->width; + while (src_data < end) { + QRgba64 s = src_data->unpremultiplied(); + *dest_data = RGBA ? ARGB2RGBA(s.toArgb32()) : s.toArgb32(); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template<bool RGBA> +static void convert_ARGB32_to_RGBA64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(RGBA || src->format == QImage::Format_ARGB32); + Q_ASSERT(!RGBA || src->format == QImage::Format_RGBA8888); + Q_ASSERT(dest->format == QImage::Format_RGBA64); + 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 >> 3) - dest->width; + const uint *src_data = reinterpret_cast<const uint *>(src->data); + QRgba64 *dest_data = reinterpret_cast<QRgba64 *>(dest->data); + + for (int i = 0; i < src->height; ++i) { + const uint *end = src_data + src->width; + while (src_data < end) { + if (RGBA) + *dest_data = QRgba64::fromArgb32(RGBA2ARGB(*src_data)); + else + *dest_data = QRgba64::fromArgb32(*src_data); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template<QtPixelOrder PixelOrder> +static void convert_RGBA64PM_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_RGB30 || dest->format == QImage::Format_BGR30); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const int src_pad = (src->bytes_per_line >> 3) - src->width; + const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; + const QRgba64 *src_data = reinterpret_cast<const QRgba64 *>(src->data); + uint *dest_data = reinterpret_cast<uint *>(dest->data); + + for (int i = 0; i < src->height; ++i) { + const QRgba64 *end = src_data + src->width; + while (src_data < end) { + *dest_data = 0xc0000000 | qConvertRgb64ToRgb30<PixelOrder>(src_data->unpremultiplied()); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template<QtPixelOrder PixelOrder> +static void convert_RGBA64PM_to_A2RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_A2RGB30_Premultiplied + || dest->format == QImage::Format_A2BGR30_Premultiplied); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const int src_pad = (src->bytes_per_line >> 3) - src->width; + const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; + const QRgba64 *src_data = reinterpret_cast<const QRgba64 *>(src->data); + uint *dest_data = reinterpret_cast<uint *>(dest->data); + + for (int i = 0; i < src->height; ++i) { + const QRgba64 *end = src_data + src->width; + while (src_data < end) { + *dest_data = qConvertRgb64ToRgb30<PixelOrder>(*src_data); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +static void convert_RGBA64_to_RGBx64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_RGBA64); + Q_ASSERT(dest->format == QImage::Format_RGBX64); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const int src_pad = (src->bytes_per_line >> 3) - src->width; + const int dest_pad = (dest->bytes_per_line >> 3) - dest->width; + const QRgba64 *src_data = reinterpret_cast<const QRgba64 *>(src->data); + QRgba64 *dest_data = reinterpret_cast<QRgba64 *>(dest->data); + + for (int i = 0; i < src->height; ++i) { + const QRgba64 *end = src_data + src->width; + while (src_data < end) { + *dest_data = *src_data; + dest_data->setAlpha(65535); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +static bool convert_RGBA64_to_RGBx64_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_RGBA64); + + const int pad = (data->bytes_per_line >> 3) - data->width; + QRgba64 *rgb_data = reinterpret_cast<QRgba64 *>(data->data); + + for (int i = 0; i < data->height; ++i) { + const QRgba64 *end = rgb_data + data->width; + while (rgb_data < end) { + rgb_data->setAlpha(65535); + ++rgb_data; + } + rgb_data += pad; + } + data->format = QImage::Format_RGBX64; + return true; +} + +static void convert_RGBA64_to_RGBA64PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_RGBA64); + Q_ASSERT(dest->format == QImage::Format_RGBA64_Premultiplied); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const int src_pad = (src->bytes_per_line >> 3) - src->width; + const int dest_pad = (dest->bytes_per_line >> 3) - dest->width; + const QRgba64 *src_data = reinterpret_cast<const QRgba64 *>(src->data); + QRgba64 *dest_data = reinterpret_cast<QRgba64 *>(dest->data); + + for (int i = 0; i < src->height; ++i) { + const QRgba64 *end = src_data + src->width; + while (src_data < end) { + *dest_data = src_data->premultiplied(); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +static bool convert_RGBA64_to_RGBA64PM_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_RGBA64); + + const int pad = (data->bytes_per_line >> 3) - data->width; + QRgba64 *rgb_data = reinterpret_cast<QRgba64 *>(data->data); + + for (int i = 0; i < data->height; ++i) { + const QRgba64 *end = rgb_data + data->width; + while (rgb_data < end) { + *rgb_data = rgb_data->premultiplied(); + ++rgb_data; + } + rgb_data += pad; + } + data->format = QImage::Format_RGBA64_Premultiplied; + return true; +} + +template<bool MaskAlpha> +static void convert_RGBA64PM_to_RGBA64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_RGBA64 || dest->format == QImage::Format_RGBX64); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const int src_pad = (src->bytes_per_line >> 3) - src->width; + const int dest_pad = (dest->bytes_per_line >> 3) - dest->width; + const QRgba64 *src_data = reinterpret_cast<const QRgba64 *>(src->data); + QRgba64 *dest_data = reinterpret_cast<QRgba64 *>(dest->data); + + for (int i = 0; i < src->height; ++i) { + const QRgba64 *end = src_data + src->width; + while (src_data < end) { + *dest_data = src_data->unpremultiplied(); + if (MaskAlpha) + dest_data->setAlpha(65535); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template<bool MaskAlpha> +static bool convert_RGBA64PM_to_RGBA64_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_RGBA64_Premultiplied); + + const int pad = (data->bytes_per_line >> 3) - data->width; + QRgba64 *rgb_data = reinterpret_cast<QRgba64 *>(data->data); + + for (int i = 0; i < data->height; ++i) { + const QRgba64 *end = rgb_data + data->width; + while (rgb_data < end) { + *rgb_data = rgb_data->unpremultiplied(); + if (MaskAlpha) + rgb_data->setAlpha(65535); + ++rgb_data; + } + rgb_data += pad; + } + data->format = MaskAlpha ? QImage::Format_RGBX64 : QImage::Format_RGBA64; + return true; +} + static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format) { QVector<QRgb> colorTable = ctbl; @@ -2032,7 +2278,7 @@ static bool convert_Grayscale8_to_Indexed8_inplace(QImageData *data, Qt::ImageCo Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormats] = { { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, @@ -2053,7 +2299,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_Mono { @@ -2075,7 +2321,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_MonoLSB { @@ -2100,6 +2346,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, 0, 0, convert_Indexed8_to_Alpha8, convert_Indexed8_to_Grayscale8, + 0, 0, 0 }, // Format_Indexed8 { @@ -2122,11 +2369,12 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - convert_RGB_to_RGB30<PixelOrderBGR>, + convert_RGB_to_RGB30<PixelOrderBGR, false>, 0, - convert_RGB_to_RGB30<PixelOrderRGB>, + convert_RGB_to_RGB30<PixelOrderRGB, false>, 0, - 0, 0 + 0, 0, + 0, 0, 0 }, // Format_RGB32 { @@ -2136,7 +2384,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_ARGB_to_Indexed8, mask_alpha_converter, 0, - convert_ARGB_to_ARGB_PM, + 0, 0, 0, 0, @@ -2149,11 +2397,14 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_ARGB_to_RGBx, convert_ARGB_to_RGBA, 0, - convert_RGB_to_RGB30<PixelOrderBGR>, + convert_RGB_to_RGB30<PixelOrderBGR, false>, 0, - convert_RGB_to_RGB30<PixelOrderRGB>, + convert_RGB_to_RGB30<PixelOrderRGB, false>, 0, - 0, 0 + 0, 0, + 0, + convert_ARGB32_to_RGBA64<false>, + 0 }, // Format_ARGB32 { @@ -2176,11 +2427,9 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, convert_ARGB_to_RGBA, - 0, - 0, - 0, - 0, - 0, 0 + 0, 0, 0, 0, + 0, 0, + 0, 0, 0 }, // Format_ARGB32_Premultiplied { @@ -2202,7 +2451,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB16 { @@ -2224,7 +2473,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB8565_Premultiplied { @@ -2246,7 +2495,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB666 { @@ -2268,7 +2517,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB6666_Premultiplied { @@ -2290,7 +2539,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB555 { @@ -2312,7 +2561,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB8555_Premultiplied { @@ -2335,7 +2584,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_RGB888_to_RGB<true>, convert_RGB888_to_RGB<true>, convert_RGB888_to_RGB<true>, - 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB888 { @@ -2357,7 +2606,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB444 { @@ -2378,7 +2627,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB4444_Premultiplied { 0, @@ -2398,9 +2647,14 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - mask_alpha_converter_RGBx, - mask_alpha_converter_RGBx, - 0, 0, 0, 0, 0, 0 + convert_passthrough, + convert_passthrough, + convert_RGB_to_RGB30<PixelOrderBGR, true>, + 0, + convert_RGB_to_RGB30<PixelOrderRGB, true>, + 0, + 0, 0, + 0, 0, 0 }, // Format_RGBX8888 { 0, @@ -2420,14 +2674,16 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, mask_alpha_converter_RGBx, -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN 0, - convert_ARGB_to_ARGB_PM, -#else 0, + convert_RGB_to_RGB30<PixelOrderBGR, true>, 0, -#endif - 0, 0, 0, 0, 0, 0 + convert_RGB_to_RGB30<PixelOrderRGB, true>, + 0, + 0, 0, + 0, + convert_ARGB32_to_RGBA64<true>, + 0 }, // Format_RGBA8888 { @@ -2449,7 +2705,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGBA8888_Premultiplied { @@ -2476,7 +2732,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_passthrough, convert_BGR30_to_RGB30, convert_BGR30_to_RGB30, - 0, 0 + 0, 0, + 0, 0, 0 }, // Format_BGR30 { 0, @@ -2484,8 +2741,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - convert_A2RGB30_PM_to_ARGB<PixelOrderBGR>, - 0, + convert_A2RGB30_PM_to_ARGB<PixelOrderBGR, false>, 0, 0, 0, @@ -2497,12 +2753,14 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, + convert_A2RGB30_PM_to_ARGB<PixelOrderBGR, true>, 0, convert_A2RGB30_PM_to_RGB30<false>, 0, convert_A2RGB30_PM_to_RGB30<true>, convert_BGR30_to_RGB30, - 0, 0 + 0, 0, + 0, 0, 0 }, // Format_BGR30A2_Premultiplied { 0, @@ -2528,7 +2786,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_BGR30_to_RGB30, 0, convert_passthrough, - 0, 0 + 0, 0, 0, 0, 0 }, // Format_RGB30 { 0, @@ -2536,8 +2794,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - convert_A2RGB30_PM_to_ARGB<PixelOrderRGB>, - 0, + convert_A2RGB30_PM_to_ARGB<PixelOrderRGB, false>, 0, 0, 0, @@ -2549,12 +2806,14 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, + convert_A2RGB30_PM_to_ARGB<PixelOrderRGB, true>, 0, convert_A2RGB30_PM_to_RGB30<true>, convert_BGR30_to_RGB30, convert_A2RGB30_PM_to_RGB30<false>, 0, - 0, 0 + 0, 0, + 0, 0, 0 }, // Format_RGB30A2_Premultiplied { 0, @@ -2574,7 +2833,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_Alpha8 { 0, @@ -2594,20 +2853,81 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 - } // Format_Grayscale8 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // Format_Grayscale8 + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, // self + convert_passthrough, + convert_passthrough + }, // Format_RGBX64 + { + 0, + 0, + 0, + 0, + 0, + convert_RGBA64_to_ARGB32<false>, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_RGBA64_to_ARGB32<true>, + 0, + 0, 0, 0, 0, + 0, 0, + convert_RGBA64_to_RGBx64, + 0, // self + convert_RGBA64_to_RGBA64PM + }, // Format_RGBA64 + { + 0, + 0, + 0, + 0, + 0, + convert_RGBA64PM_to_ARGB32<false>, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_RGBA64PM_to_ARGB32<true>, + 0, + convert_RGBA64PM_to_RGB30<PixelOrderBGR>, + convert_RGBA64PM_to_A2RGB30<PixelOrderBGR>, + convert_RGBA64PM_to_RGB30<PixelOrderRGB>, + convert_RGBA64PM_to_A2RGB30<PixelOrderRGB>, + 0, 0, + convert_RGBA64PM_to_RGBA64<true>, + convert_RGBA64PM_to_RGBA64<false>, + 0 // self + } // Format_RGBA64_Premultiplied }; InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] = { { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_Mono { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_MonoLSB { 0, @@ -2631,6 +2951,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, 0, 0, convert_Indexed8_to_Alpha8_inplace, convert_Indexed8_to_Grayscale8_inplace, + 0, 0, 0 }, // Format_Indexed8 { 0, @@ -2652,11 +2973,12 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - convert_RGB_to_RGB30_inplace<PixelOrderBGR>, + convert_RGB_to_RGB30_inplace<PixelOrderBGR, false>, 0, - convert_RGB_to_RGB30_inplace<PixelOrderRGB>, + convert_RGB_to_RGB30_inplace<PixelOrderRGB, false>, 0, - 0, 0 + 0, 0, + 0, 0, 0 }, // Format_RGB32 { 0, @@ -2665,11 +2987,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 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, -#endif + 0, 0, 0, 0, @@ -2682,11 +3000,12 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_ARGB_to_RGBA_inplace<QImage::Format_RGBX8888>, convert_ARGB_to_RGBA_inplace<QImage::Format_RGBA8888>, 0, - convert_RGB_to_RGB30_inplace<PixelOrderBGR>, + convert_RGB_to_RGB30_inplace<PixelOrderBGR, false>, 0, - convert_RGB_to_RGB30_inplace<PixelOrderRGB>, + convert_RGB_to_RGB30_inplace<PixelOrderRGB, false>, 0, - 0, 0 + 0, 0, + 0, 0, 0 }, // Format_ARGB32 { 0, @@ -2708,38 +3027,36 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, convert_ARGB_to_RGBA_inplace<QImage::Format_RGBA8888_Premultiplied>, - 0, - 0, - 0, - 0, - 0, 0 + 0, 0, 0, 0, + 0, 0, + 0, 0, 0 }, // Format_ARGB32_Premultiplied { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB16 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB8565_Premultiplied { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB666 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB6666_Premultiplied { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB555 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB8555_Premultiplied { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB888 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB444 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB4444_Premultiplied { 0, @@ -2761,7 +3078,12 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, convert_passthrough_inplace<QImage::Format_RGBA8888>, convert_passthrough_inplace<QImage::Format_RGBA8888_Premultiplied>, - 0, 0, 0, 0, 0, 0 + convert_RGB_to_RGB30_inplace<PixelOrderBGR, true>, + 0, + convert_RGB_to_RGB30_inplace<PixelOrderRGB, true>, + 0, + 0, 0, + 0, 0, 0 }, // Format_RGBX8888 { 0, @@ -2782,14 +3104,13 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, mask_alpha_converter_rgbx_inplace, 0, -#ifdef __SSE2__ - convert_ARGB_to_ARGB_PM_inplace_sse2, -#elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN - convert_ARGB_to_ARGB_PM_inplace, -#else 0, -#endif - 0, 0, 0, 0, 0, 0 + convert_RGB_to_RGB30_inplace<PixelOrderBGR, true>, + 0, + convert_RGB_to_RGB30_inplace<PixelOrderRGB, true>, + 0, + 0, 0, + 0, 0, 0 }, // Format_RGBA8888 { 0, @@ -2811,7 +3132,7 @@ 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, 0 }, // Format_RGBA8888_Premultiplied { 0, @@ -2837,7 +3158,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_passthrough_inplace<QImage::Format_A2BGR30_Premultiplied>, convert_BGR30_to_RGB30_inplace, convert_BGR30_to_A2RGB30_inplace, - 0, 0 + 0, 0, + 0, 0, 0 }, // Format_BGR30 { 0, @@ -2845,8 +3167,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - convert_A2RGB30_PM_to_ARGB_inplace<PixelOrderBGR>, - 0, + convert_A2RGB30_PM_to_ARGB_inplace<PixelOrderBGR, false>, 0, 0, 0, @@ -2858,12 +3179,13 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, + convert_A2RGB30_PM_to_ARGB_inplace<PixelOrderBGR, true>, 0, convert_A2RGB30_PM_to_RGB30_inplace<false>, 0, // self convert_A2RGB30_PM_to_RGB30_inplace<true>, convert_BGR30_to_RGB30_inplace, - 0, 0 + 0, 0, 0, 0, 0 }, // Format_BGR30A2_Premultiplied { 0, @@ -2889,7 +3211,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_BGR30_to_A2RGB30_inplace, 0, // self convert_passthrough_inplace<QImage::Format_A2RGB30_Premultiplied>, - 0, 0 + 0, 0, 0, 0, 0 }, // Format_RGB30 { 0, @@ -2897,8 +3219,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - convert_A2RGB30_PM_to_ARGB_inplace<PixelOrderRGB>, - 0, + convert_A2RGB30_PM_to_ARGB_inplace<PixelOrderRGB, false>, 0, 0, 0, @@ -2910,12 +3231,14 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, + convert_A2RGB30_PM_to_ARGB_inplace<PixelOrderRGB, true>, 0, convert_A2RGB30_PM_to_RGB30_inplace<true>, convert_BGR30_to_RGB30_inplace, convert_A2RGB30_PM_to_RGB30_inplace<false>, 0, // self - 0, 0 + 0, 0, + 0, 0, 0 }, // Format_RGB30A2_Premultiplied { 0, @@ -2937,11 +3260,10 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, + 0, 0, 0, 0, + 0, // self 0, - 0, - 0, - 0, - 0, 0 + 0, 0, 0 }, // Format_Alpha8 { 0, @@ -2963,12 +3285,29 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, + 0, 0, 0, 0, 0, - 0, - 0, - 0, - 0, 0 - } // Format_Grayscale8 + 0, // self + 0, 0, 0 + }, // Format_Grayscale8 + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, // self + convert_passthrough_inplace<QImage::Format_RGBA64>, + convert_passthrough_inplace<QImage::Format_RGBA64_Premultiplied>, + }, // Format_RGBX64 + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + convert_RGBA64_to_RGBx64_inplace, + 0, // self + convert_RGBA64_to_RGBA64PM_inplace + }, // Format_RGBA64 + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + convert_RGBA64PM_to_RGBA64_inplace<true>, + convert_RGBA64PM_to_RGBA64_inplace<false>, + 0 // self + } // Format_RGBA64_Premultiplied }; static void qInitImageConversions() @@ -2982,22 +3321,6 @@ static void qInitImageConversions() } #endif -#if defined(QT_COMPILER_SUPPORTS_SSE4_1) && !defined(__SSE4_1__) - if (qCpuHasFeature(SSE4_1)) { - extern void convert_ARGB_to_ARGB_PM_sse4(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); - 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; - } -#endif - -#if defined(QT_COMPILER_SUPPORTS_AVX2) && !defined(__AVX2__) - if (qCpuHasFeature(AVX2)) { - extern void convert_ARGB_to_ARGB_PM_avx2(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); - qimage_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_avx2; - qimage_converter_map[QImage::Format_RGBA8888][QImage::Format_RGBA8888_Premultiplied] = convert_ARGB_to_ARGB_PM_avx2; - } -#endif - #if defined(__ARM_NEON__) extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon; |