diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2013-07-03 15:13:55 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-07-23 16:30:06 +0200 |
commit | 36e6376755ce0f5dcd022e11d2539f125980a96b (patch) | |
tree | ac146b02e9a6f9197d03f2ec562b70dc14e7c901 /src | |
parent | d24b4a5548c941a7b9bed9888094d9c1be8d6ca3 (diff) |
Support RGBA image format
Support the byte-ordered RGBA format which is used by OpenGL, and many
endian neutral byte formats.
Task-number: QTBUG-32201
Change-Id: I77cffb4c30c69545fa96ded2f537b2ebd9351acb
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/image/qbmphandler.cpp | 3 | ||||
-rw-r--r-- | src/gui/image/qimage.cpp | 689 | ||||
-rw-r--r-- | src/gui/image/qimage.h | 3 | ||||
-rw-r--r-- | src/gui/image/qimage_p.h | 3 | ||||
-rw-r--r-- | src/gui/image/qppmhandler.cpp | 3 | ||||
-rw-r--r-- | src/gui/image/qxpmhandler.cpp | 2 | ||||
-rw-r--r-- | src/gui/opengl/qopenglframebufferobject.cpp | 21 | ||||
-rw-r--r-- | src/gui/painting/qblendfunctions.cpp | 465 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 170 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper_p.h | 24 | ||||
-rw-r--r-- | src/gui/painting/qimagescale.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qmemrotate.cpp | 5 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 4 |
13 files changed, 1295 insertions, 99 deletions
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index cb4e45f1d0..c03d9b8e5d 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -781,6 +781,8 @@ bool QBmpHandler::write(const QImage &img) case QImage::Format_ARGB8555_Premultiplied: case QImage::Format_ARGB6666_Premultiplied: case QImage::Format_ARGB4444_Premultiplied: + case QImage::Format_RGBA8888: + case QImage::Format_RGBA8888_Premultiplied: image = img.convertToFormat(QImage::Format_ARGB32); break; case QImage::Format_RGB16: @@ -788,6 +790,7 @@ bool QBmpHandler::write(const QImage &img) case QImage::Format_RGB666: case QImage::Format_RGB555: case QImage::Format_RGB444: + case QImage::Format_RGBX8888: image = img.convertToFormat(QImage::Format_RGB32); break; default: diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 98f3aeeeb9..8e5f6391a7 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -212,6 +212,16 @@ bool QImageData::checkForAlphaPixels() const } } break; + case QImage::Format_RGBA8888: + case QImage::Format_RGBA8888_Premultiplied: { + uchar *bits = data; + for (int y=0; y<height && !has_alpha_pixels; ++y) { + for (int x=0; x<width; ++x) + has_alpha_pixels |= bits[x*4+3] != 0xff; + bits += bytes_per_line; + } + } break; + case QImage::Format_ARGB8555_Premultiplied: case QImage::Format_ARGB8565_Premultiplied: { uchar *bits = data; @@ -621,9 +631,9 @@ bool QImageData::checkForAlphaPixels() const /*! \enum QImage::Format - The following image formats are available in Qt. Values greater - than QImage::Format_RGB16 were added in Qt 4.4. See the notes - after the table. + The following image formats are available in Qt. Values from Format_ARGB8565_Premultiplied + to Format_ARGB4444_Premultiplied were added in Qt 4.4. Values Format_RGBX8888, Format_RGBA8888 + and Format_RGBA8888_Premultiplied were added in Qt 5.2. See the notes after the table. \value Format_Invalid The image is invalid. \value Format_Mono The image is stored using 1-bit per pixel. Bytes are @@ -665,6 +675,15 @@ bool QImageData::checkForAlphaPixels() const The unused bits are always zero. \value Format_ARGB4444_Premultiplied The image is stored using a premultiplied 16-bit ARGB format (4-4-4-4). + \value Format_RGBX8888 The image is stored using a 32-bit byte-ordered RGB(x) format (8-8-8-8). + This is the same as the Format_RGBA8888 except alpha must always be 255. + \value Format_RGBA8888 The image is stored using a 32-bit byte-ordered RGBA format (8-8-8-8). + Unlike ARGB32 this is a byte-ordered format, which means the 32bit + encoding differs between big endian and little endian architectures, + being respectively (0xRRGGBBAA) and (0xAABBGGRR). The order of the colors + is the same on any architecture if read as bytes 0xRR,0xGG,0xBB,0xAA. + \value Format_RGBA8888_Premultiplied The image is stored using a + premultiplied 32-bit byte-ordered RGBA format (8-8-8-8). \note Drawing into a QImage with QImage::Format_Indexed8 is not supported. @@ -1663,9 +1682,12 @@ void QImage::fill(uint pixel) return; } - if (d->format == Format_RGB32) + if (d->format == Format_RGB32 || d->format == Format_RGBX8888) pixel |= 0xff000000; + if (d->format == Format_RGBX8888 || d->format == Format_RGBA8888 || d->format == Format_RGBA8888_Premultiplied) + pixel = ARGB2RGBA(pixel); + qt_rectfill<uint>(reinterpret_cast<uint*>(d->data), pixel, 0, 0, d->width, d->height, d->bytes_per_line); } @@ -1716,7 +1738,7 @@ void QImage::fill(const QColor &color) if (d->depth == 32) { uint pixel = color.rgba(); - if (d->format == QImage::Format_ARGB32_Premultiplied) + if (d->format == QImage::Format_ARGB32_Premultiplied || d->format == QImage::Format_RGBA8888_Premultiplied) pixel = PREMUL(pixel); fill((uint) pixel); @@ -1871,8 +1893,8 @@ typedef bool (*InPlace_Image_Converter)(QImageData *data, Qt::ImageConversionFla static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { - Q_ASSERT(src->format == QImage::Format_ARGB32); - Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied); + 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); @@ -1912,6 +1934,191 @@ static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversio return true; } +static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_ARGB32); + 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 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(0xff000000 | *src_data); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +static void convert_ARGB_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_ARGB32_Premultiplied); + Q_ASSERT(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 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(*src_data); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +static bool convert_ARGB_to_RGBA_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_ARGB32_Premultiplied); + + const int pad = (data->bytes_per_line >> 2) - data->width; + quint32 *rgb_data = (quint32 *) data->data; + + for (int i = 0; i < data->height; ++i) { + const quint32 *end = rgb_data + data->width; + while (rgb_data < end) { + *rgb_data = ARGB2RGBA(*rgb_data); + ++rgb_data; + } + rgb_data += pad; + } + if (data->format == QImage::Format_ARGB32) + data->format = QImage::Format_RGBA8888; + else + data->format = QImage::Format_RGBA8888_Premultiplied; + return true; +} + +static 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(PREMUL(*src_data)); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +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); + Q_ASSERT(dest->format == QImage::Format_ARGB32 || 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 = RGBA2ARGB(*src_data); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +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; + + 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 = PREMUL(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 = PREMUL(RGBA2ARGB(*rgb_data)); + ++rgb_data; + } + rgb_data += pad; + } + data->format = QImage::Format_ARGB32_Premultiplied; + return true; +} + static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags) { Q_ASSERT(data->format == QImage::Format_Indexed8); @@ -2099,8 +2306,8 @@ 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) { - Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied); - Q_ASSERT(dest->format == QImage::Format_ARGB32); + Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied || src->format == QImage::Format_RGBA8888_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888); Q_ASSERT(src->width == dest->width); Q_ASSERT(src->height == dest->height); @@ -2123,20 +2330,164 @@ 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 | INV_PREMUL(*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 | INV_PREMUL(*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(INV_PREMUL(*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); 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 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 = RGBA2ARGB(*src_data) | 0xff000000; + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +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 = 0xff000000 | INV_PREMUL(*src_data); + *dest_data = INV_PREMUL(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 | INV_PREMUL(RGBA2ARGB(*src_data)); ++src_data; ++dest_data; } @@ -2188,6 +2539,33 @@ static void mask_alpha_converter(QImageData *dest, const QImageData *src, Qt::Im } } +static void mask_alpha_converter_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags) +{ +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + return mask_alpha_converter(dest, src, flags); +#else + Q_UNUSED(flags); + 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 = *src_data | 0x000000ff; + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +#endif +} + static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format) { QVector<QRgb> colorTable = ctbl; @@ -2941,6 +3319,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, + 0, + 0, + 0, 0 }, // Format_Mono @@ -2960,6 +3341,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, + 0, + 0, + 0, 0 }, // Format_MonoLSB @@ -2979,6 +3363,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, + 0, + 0, + 0, 0 }, // Format_Indexed8 @@ -2998,7 +3385,10 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat convert_generic, convert_generic, convert_generic, - convert_generic + convert_generic, + convert_RGB_to_RGBA, + convert_RGB_to_RGBA, + convert_RGB_to_RGBA }, // Format_RGB32 { @@ -3017,7 +3407,10 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat convert_generic, convert_generic, convert_generic, - convert_generic + convert_generic, + convert_ARGB_to_RGBx, + convert_ARGB_to_RGBA, + convert_ARGB_to_RGBA_PM, }, // Format_ARGB32 { @@ -3036,7 +3429,10 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, + convert_ARGB_PM_to_RGBx, + convert_ARGB_PM_to_RGBA, + convert_ARGB_to_RGBA, }, // Format_ARGB32_Premultiplied { @@ -3059,6 +3455,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, + 0, + 0, + 0, 0 }, // Format_RGB16 @@ -3078,6 +3477,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, + 0, + 0, + 0, 0 }, // Format_ARGB8565_Premultiplied @@ -3097,6 +3499,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, + 0, + 0, + 0, 0 }, // Format_RGB666 @@ -3116,6 +3521,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, + 0, + 0, + 0, 0 }, // Format_ARGB6666_Premultiplied @@ -3139,6 +3547,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, + 0, + 0, + 0, 0 }, // Format_RGB555 @@ -3158,6 +3569,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, + 0, + 0, + 0, 0 }, // Format_ARGB8555_Premultiplied @@ -3177,6 +3591,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, + 0, + 0, + 0, 0 }, // Format_RGB888 @@ -3196,6 +3613,9 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, + 0, + 0, + 0, 0 }, // Format_RGB444 @@ -3215,20 +3635,97 @@ static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, + 0, + 0, 0 - } // Format_ARGB4444_Premultiplied + }, // Format_ARGB4444_Premultiplied + { + 0, + 0, + 0, + 0, + convert_RGBA_to_RGB, + convert_RGBA_to_ARGB, + convert_RGBA_to_ARGB_PM, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + mask_alpha_converter_RGBx, + mask_alpha_converter_RGBx, + }, // Format_RGBX8888 + { + 0, + 0, + 0, + 0, + convert_RGBA_to_RGB, + convert_RGBA_to_ARGB, + convert_RGBA_to_ARGB_PM, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + mask_alpha_converter_RGBx, +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + 0, + convert_ARGB_to_ARGB_PM, +#else + 0, + 0 +#endif + }, // Format_RGBA8888 + + { + 0, + 0, + 0, + 0, + convert_RGBA_PM_to_RGB, + convert_RGBA_PM_to_ARGB, + convert_RGBA_to_ARGB, + 0, + 0, + 0, + 0, + 0, + 0, + 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 + } // Format_RGBA8888_Premultiplied }; static InPlace_Image_Converter 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 }, // 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 }, // Format_MonoLSB { 0, @@ -3247,6 +3744,9 @@ static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, + 0, + 0, + 0, }, // Format_Indexed8 { 0, @@ -3265,7 +3765,10 @@ static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - }, // Format_ARGB32 + 0, + 0, + 0, + }, // Format_RGB32 { 0, 0, @@ -3283,37 +3786,118 @@ static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, + 0, + convert_ARGB_to_RGBA_inplace, + 0, }, // Format_ARGB32 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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_ARGB_to_RGBA_inplace }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // Format_RGB444 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } // Format_ARGB4444_Premultiplied + 0, + 0, + 0, + 0, + 0, + convert_RGBA_to_ARGB_inplace, + convert_RGBA_to_ARGB_inplace, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + }, // Format_RGBX8888 + { + 0, + 0, + 0, + 0, + 0, + 0, + convert_RGBA_to_ARGB_inplace, + convert_RGBA_to_ARGB_PM_inplace, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + }, // Format_RGBA8888 + { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_RGBA_to_ARGB_inplace, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + } // Format_RGBA8888_Premultiplied }; void qInitImageConversions() @@ -3633,6 +4217,10 @@ QRgb QImage::pixel(int x, int y) const case Format_ARGB32: // Keep old behaviour. case Format_ARGB32_Premultiplied: return reinterpret_cast<const QRgb *>(s)[x]; + case Format_RGBX8888: + case Format_RGBA8888: // Match ARGB32 behavior. + case Format_RGBA8888_Premultiplied: + return RGBA2ARGB(reinterpret_cast<const quint32 *>(s)[x]); case Format_RGB16: return qConvertRgb16To32(reinterpret_cast<const quint16 *>(s)[x]); default: @@ -3716,6 +4304,13 @@ void QImage::setPixel(int x, int y, uint index_or_rgb) case Format_RGB16: ((quint16 *)s)[x] = qConvertRgb32To16(INV_PREMUL(index_or_rgb)); return; + case Format_RGBX8888: + ((uint *)s)[x] = ARGB2RGBA(index_or_rgb | 0xff000000); + return; + case Format_RGBA8888: + case Format_RGBA8888_Premultiplied: + ((uint *)s)[x] = ARGB2RGBA(index_or_rgb); + return; case Format_Invalid: case NImageFormats: Q_ASSERT(false); @@ -3756,6 +4351,11 @@ bool QImage::allGray() const case Format_RGB32: case Format_ARGB32: case Format_ARGB32_Premultiplied: +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + case Format_RGBX8888: + case Format_RGBA8888: + case Format_RGBA8888_Premultiplied: +#endif for (int j = 0; j < d->height; ++j) { const QRgb *b = (const QRgb *)constScanLine(j); for (int i = 0; i < d->width; ++i) { @@ -4330,6 +4930,11 @@ QImage QImage::rgbSwapped() const case Format_RGB32: case Format_ARGB32: case Format_ARGB32_Premultiplied: +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + case Format_RGBX8888: + case Format_RGBA8888: + case Format_RGBA8888_Premultiplied: +#endif res = QImage(d->width, d->height, d->format); QIMAGE_SANITYCHECK_MEMORY(res); for (int i = 0; i < d->height; i++) { @@ -5373,7 +5978,11 @@ QImage QImage::alphaChannel() const } } else { QImage alpha32 = *this; - if (d->format != Format_ARGB32 && d->format != Format_ARGB32_Premultiplied) + bool canSkipConversion = (d->format == Format_ARGB32 || d->format == Format_ARGB32_Premultiplied); +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + canSkipConversion = canSkipConversion || (d->format == Format_RGBA8888 || d->format == Format_RGBA8888_Premultiplied); +#endif + if (!canSkipConversion) alpha32 = convertToFormat(Format_ARGB32); const uchar *src_data = alpha32.d->data; @@ -5408,6 +6017,8 @@ bool QImage::hasAlphaChannel() const || d->format == Format_ARGB8555_Premultiplied || d->format == Format_ARGB6666_Premultiplied || d->format == Format_ARGB4444_Premultiplied + || d->format == Format_RGBA8888 + || d->format == Format_RGBA8888_Premultiplied || (d->has_alpha_clut && (d->format == Format_Indexed8 || d->format == Format_Mono || d->format == Format_MonoLSB))); @@ -5434,6 +6045,7 @@ int QImage::bitPlaneCount() const case QImage::Format_Invalid: break; case QImage::Format_RGB32: + case QImage::Format_RGBX8888: bpc = 24; break; case QImage::Format_RGB666: @@ -5457,9 +6069,11 @@ int QImage::bitPlaneCount() const static QImage smoothScaled(const QImage &source, int w, int h) { QImage src = source; - if (src.format() == QImage::Format_ARGB32) - src = src.convertToFormat(QImage::Format_ARGB32_Premultiplied); - else if (src.depth() < 32) { + bool canSkipConversion = (src.format() == QImage::Format_RGB32 || src.format() == QImage::Format_ARGB32_Premultiplied); +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + canSkipConversion = canSkipConversion || (src.format() == QImage::Format_RGBX8888 || src.format() == QImage::Format_RGBA8888_Premultiplied); +#endif + if (!canSkipConversion) { if (src.hasAlphaChannel()) src = src.convertToFormat(QImage::Format_ARGB32_Premultiplied); else @@ -5480,6 +6094,9 @@ static QImage rotated90(const QImage &image) { case QImage::Format_RGB32: case QImage::Format_ARGB32: case QImage::Format_ARGB32_Premultiplied: + case QImage::Format_RGBX8888: + case QImage::Format_RGBA8888: + case QImage::Format_RGBA8888_Premultiplied: qt_memrotate270(reinterpret_cast<const quint32*>(image.bits()), w, h, image.bytesPerLine(), reinterpret_cast<quint32*>(out.bits()), @@ -5539,6 +6156,9 @@ static QImage rotated270(const QImage &image) { case QImage::Format_RGB32: case QImage::Format_ARGB32: case QImage::Format_ARGB32_Premultiplied: + case QImage::Format_RGBX8888: + case QImage::Format_RGBA8888: + case QImage::Format_RGBA8888_Premultiplied: qt_memrotate90(reinterpret_cast<const quint32*>(image.bits()), w, h, image.bytesPerLine(), reinterpret_cast<quint32*>(out.bits()), @@ -5684,6 +6304,9 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode case QImage::Format_RGB444: target_format = Format_ARGB4444_Premultiplied; break; + case QImage::Format_RGBX8888: + target_format = Format_RGBA8888_Premultiplied; + break; default: target_format = Format_ARGB32_Premultiplied; break; diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index a4aaf049f0..02f0c18243 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -110,6 +110,9 @@ public: Format_RGB888, Format_RGB444, Format_ARGB4444_Premultiplied, + Format_RGBX8888, + Format_RGBA8888, + Format_RGBA8888_Premultiplied, #if 0 // reserved for future use Format_RGB15, diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index 18c686e917..36f117df60 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -128,6 +128,9 @@ inline int qt_depthForFormat(QImage::Format format) case QImage::Format_RGB32: case QImage::Format_ARGB32: case QImage::Format_ARGB32_Premultiplied: + case QImage::Format_RGBX8888: + case QImage::Format_RGBA8888: + case QImage::Format_RGBA8888_Premultiplied: depth = 32; break; case QImage::Format_RGB555: diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp index 6fc41df77c..39f63a620c 100644 --- a/src/gui/image/qppmhandler.cpp +++ b/src/gui/image/qppmhandler.cpp @@ -274,12 +274,15 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy case QImage::Format_RGB555: case QImage::Format_RGB888: case QImage::Format_RGB444: + case QImage::Format_RGBX8888: image = image.convertToFormat(QImage::Format_RGB32); break; case QImage::Format_ARGB8565_Premultiplied: case QImage::Format_ARGB6666_Premultiplied: case QImage::Format_ARGB8555_Premultiplied: case QImage::Format_ARGB4444_Premultiplied: + case QImage::Format_RGBA8888: + case QImage::Format_RGBA8888_Premultiplied: image = image.convertToFormat(QImage::Format_ARGB32); break; default: diff --git a/src/gui/image/qxpmhandler.cpp b/src/gui/image/qxpmhandler.cpp index a7936f915d..3bd8ca92b4 100644 --- a/src/gui/image/qxpmhandler.cpp +++ b/src/gui/image/qxpmhandler.cpp @@ -1092,7 +1092,7 @@ static bool write_xpm_image(const QImage &sourceImage, QIODevice *device, const return false; QImage image; - if (sourceImage.depth() != 32) + if (sourceImage.format() != QImage::Format_RGB32 || sourceImage.format() != QImage::Format_ARGB32 || sourceImage.format() != QImage::Format_ARGB32_Premultiplied) image = sourceImage.convertToFormat(QImage::Format_RGB32); else image = sourceImage; diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index 90416db72b..247ecf7351 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -1012,23 +1012,28 @@ QOpenGLFramebufferObjectFormat QOpenGLFramebufferObject::format() const Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha) { - QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied - : QImage::Format_RGB32); int w = size.width(); int h = size.height(); + while (glGetError()); + +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied + : QImage::Format_RGB32); #ifdef QT_OPENGL_ES GLint fmt = GL_BGRA_EXT; #else GLint fmt = GL_BGRA; #endif - while (glGetError()); glReadPixels(0, 0, w, h, fmt, GL_UNSIGNED_BYTE, img.bits()); - if (glGetError()) { - glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); - img = img.rgbSwapped(); - } - return img.mirrored(); + if (!glGetError()) + return img.mirrored(); +#endif + + QImage rgbaImage(size, (alpha_format && include_alpha) ? QImage::Format_RGBA8888_Premultiplied + : QImage::Format_RGBX8888); + glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rgbaImage.bits()); + return rgbaImage.mirrored(); } /*! diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index 6d9168ecf4..23eaa9a3e7 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -604,7 +604,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_Mono 0, // Format_Invalid, @@ -622,7 +625,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_MonoLSB 0, // Format_Invalid, @@ -640,7 +646,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_Indexed8 0, // Format_Invalid, @@ -658,7 +667,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB32 0, // Format_Invalid, @@ -676,7 +688,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB32 0, // Format_Invalid, @@ -694,7 +709,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB32_Premultiplied 0, // Format_Invalid, @@ -712,7 +730,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB16 0, // Format_Invalid, @@ -730,7 +751,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB8565_Premultiplied 0, // Format_Invalid, @@ -748,7 +772,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB666 0, // Format_Invalid, @@ -766,7 +793,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB6666_Premultiplied 0, // Format_Invalid, @@ -784,7 +814,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB555 0, // Format_Invalid, @@ -802,7 +835,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB8555_Premultiplied 0, // Format_Invalid, @@ -820,7 +856,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB888 0, // Format_Invalid, @@ -838,7 +877,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB444 0, // Format_Invalid, @@ -856,7 +898,10 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB4444_Premultiplied 0, // Format_Invalid, @@ -874,7 +919,85 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, + }, + { // Format_RGBX8888 + 0, // Format_Invalid, + 0, // Format_Mono, + 0, // Format_MonoLSB, + 0, // Format_Indexed8, + 0, // Format_RGB32, + 0, // Format_ARGB32, + 0, // Format_ARGB32_Premultiplied, + 0, // Format_RGB16, + 0, // Format_ARGB8565_Premultiplied, + 0, // Format_RGB666, + 0, // Format_ARGB6666_Premultiplied, + 0, // Format_RGB555, + 0, // Format_ARGB8555_Premultiplied, + 0, // Format_RGB888, + 0, // Format_RGB444, + 0, // Format_ARGB4444_Premultiplied, +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + qt_scale_image_rgb32_on_rgb32, // Format_RGBX8888, + 0, // Format_RGBA8888, + qt_scale_image_argb32_on_argb32, // Format_RGBA8888_Premultiplied, +#else + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, +#endif + }, + { // Format_RGBA8888 + 0, // Format_Invalid, + 0, // Format_Mono, + 0, // Format_MonoLSB, + 0, // Format_Indexed8, + 0, // Format_RGB32, + 0, // Format_ARGB32, + 0, // Format_ARGB32_Premultiplied, + 0, // Format_RGB16, + 0, // Format_ARGB8565_Premultiplied, + 0, // Format_RGB666, + 0, // Format_ARGB6666_Premultiplied, + 0, // Format_RGB555, + 0, // Format_ARGB8555_Premultiplied, + 0, // Format_RGB888, + 0, // Format_RGB444, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, + }, + { // Format_RGBA8888_Premultiplied + 0, // Format_Invalid, + 0, // Format_Mono, + 0, // Format_MonoLSB, + 0, // Format_Indexed8, + 0, // Format_RGB32, + 0, // Format_ARGB32, + 0, // Format_ARGB32_Premultiplied, + 0, // Format_RGB16, + 0, // Format_ARGB8565_Premultiplied, + 0, // Format_RGB666, + 0, // Format_ARGB6666_Premultiplied, + 0, // Format_RGB555, + 0, // Format_ARGB8555_Premultiplied, + 0, // Format_RGB888, + 0, // Format_RGB444, + 0, // Format_ARGB4444_Premultiplied, +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + qt_scale_image_rgb32_on_rgb32, // Format_RGBX8888, + 0, // Format_RGBA8888, + qt_scale_image_argb32_on_argb32, // Format_RGBA8888_Premultiplied, +#else + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, +#endif } }; @@ -896,7 +1019,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_Mono 0, // Format_Invalid, @@ -914,7 +1040,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_MonoLSB 0, // Format_Invalid, @@ -932,7 +1061,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_Indexed8 0, // Format_Invalid, @@ -950,7 +1082,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB32 0, // Format_Invalid, @@ -968,7 +1103,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB32 0, // Format_Invalid, @@ -986,7 +1124,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB32_Premultiplied 0, // Format_Invalid, @@ -1004,7 +1145,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB16 0, // Format_Invalid, @@ -1022,7 +1166,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB8565_Premultiplied 0, // Format_Invalid, @@ -1040,7 +1187,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB666 0, // Format_Invalid, @@ -1058,7 +1208,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB6666_Premultiplied 0, // Format_Invalid, @@ -1076,7 +1229,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB555 0, // Format_Invalid, @@ -1094,7 +1250,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB8555_Premultiplied 0, // Format_Invalid, @@ -1112,7 +1271,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB888 0, // Format_Invalid, @@ -1130,7 +1292,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB444 0, // Format_Invalid, @@ -1148,7 +1313,10 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB4444_Premultiplied 0, // Format_Invalid, @@ -1166,7 +1334,85 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, + }, + { // Format_RGBX8888 + 0, // Format_Invalid, + 0, // Format_Mono, + 0, // Format_MonoLSB, + 0, // Format_Indexed8, + 0, // Format_RGB32, + 0, // Format_ARGB32, + 0, // Format_ARGB32_Premultiplied, + 0, // Format_RGB16, + 0, // Format_ARGB8565_Premultiplied, + 0, // Format_RGB666, + 0, // Format_ARGB6666_Premultiplied, + 0, // Format_RGB555, + 0, // Format_ARGB8555_Premultiplied, + 0, // Format_RGB888, + 0, // Format_RGB444, + 0, // Format_ARGB4444_Premultiplied, +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + qt_blend_rgb32_on_rgb32, // Format_RGBX8888, + 0, // Format_RGBA8888, + qt_blend_argb32_on_argb32, // Format_RGBA8888_Premultiplied, +#else + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, +#endif + }, + { // Format_RGBA8888 + 0, // Format_Invalid, + 0, // Format_Mono, + 0, // Format_MonoLSB, + 0, // Format_Indexed8, + 0, // Format_RGB32, + 0, // Format_ARGB32, + 0, // Format_ARGB32_Premultiplied, + 0, // Format_RGB16, + 0, // Format_ARGB8565_Premultiplied, + 0, // Format_RGB666, + 0, // Format_ARGB6666_Premultiplied, + 0, // Format_RGB555, + 0, // Format_ARGB8555_Premultiplied, + 0, // Format_RGB888, + 0, // Format_RGB444, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, + }, + { // Format_RGBA8888_Premultiplied + 0, // Format_Invalid, + 0, // Format_Mono, + 0, // Format_MonoLSB, + 0, // Format_Indexed8, + 0, // Format_RGB32, + 0, // Format_ARGB32, + 0, // Format_ARGB32_Premultiplied, + 0, // Format_RGB16, + 0, // Format_ARGB8565_Premultiplied, + 0, // Format_RGB666, + 0, // Format_ARGB6666_Premultiplied, + 0, // Format_RGB555, + 0, // Format_ARGB8555_Premultiplied, + 0, // Format_RGB888, + 0, // Format_RGB444, + 0, // Format_ARGB4444_Premultiplied, +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + qt_blend_rgb32_on_rgb32, // Format_RGBX8888, + 0, // Format_RGBA8888, + qt_blend_argb32_on_argb32, // Format_RGBA8888_Premultiplied, +#else + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, +#endif } }; @@ -1187,7 +1433,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_Mono 0, // Format_Invalid, @@ -1205,7 +1454,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_MonoLSB 0, // Format_Invalid, @@ -1223,7 +1475,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_Indexed8 0, // Format_Invalid, @@ -1241,7 +1496,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB32 0, // Format_Invalid, @@ -1259,7 +1517,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB32 0, // Format_Invalid, @@ -1277,7 +1538,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB32_Premultiplied 0, // Format_Invalid, @@ -1295,7 +1559,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB16 0, // Format_Invalid, @@ -1313,7 +1580,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB8565_Premultiplied 0, // Format_Invalid, @@ -1331,7 +1601,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB666 0, // Format_Invalid, @@ -1349,7 +1622,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB6666_Premultiplied 0, // Format_Invalid, @@ -1367,7 +1643,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB555 0, // Format_Invalid, @@ -1385,7 +1664,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB8555_Premultiplied 0, // Format_Invalid, @@ -1403,7 +1685,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB888 0, // Format_Invalid, @@ -1421,7 +1706,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_RGB444 0, // Format_Invalid, @@ -1439,7 +1727,10 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, }, { // Format_ARGB4444_Premultiplied 0, // Format_Invalid, @@ -1457,7 +1748,85 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB8555_Premultiplied, 0, // Format_RGB888, 0, // Format_RGB444, - 0 // Format_ARGB4444_Premultiplied, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, + }, + { // Format_RGBX8888 + 0, // Format_Invalid, + 0, // Format_Mono, + 0, // Format_MonoLSB, + 0, // Format_Indexed8, + 0, // Format_RGB32, + 0, // Format_ARGB32, + 0, // Format_ARGB32_Premultiplied, + 0, // Format_RGB16, + 0, // Format_ARGB8565_Premultiplied, + 0, // Format_RGB666, + 0, // Format_ARGB6666_Premultiplied, + 0, // Format_RGB555, + 0, // Format_ARGB8555_Premultiplied, + 0, // Format_RGB888, + 0, // Format_RGB444, + 0, // Format_ARGB4444_Premultiplied, +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + qt_transform_image_rgb32_on_rgb32, // Format_RGBX8888, + 0, // Format_RGBA8888, + qt_transform_image_argb32_on_argb32, // Format_RGBA8888_Premultiplied, +#else + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, +#endif + }, + { // Format_RGBA8888 + 0, // Format_Invalid, + 0, // Format_Mono, + 0, // Format_MonoLSB, + 0, // Format_Indexed8, + 0, // Format_RGB32, + 0, // Format_ARGB32, + 0, // Format_ARGB32_Premultiplied, + 0, // Format_RGB16, + 0, // Format_ARGB8565_Premultiplied, + 0, // Format_RGB666, + 0, // Format_ARGB6666_Premultiplied, + 0, // Format_RGB555, + 0, // Format_ARGB8555_Premultiplied, + 0, // Format_RGB888, + 0, // Format_RGB444, + 0, // Format_ARGB4444_Premultiplied, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, + }, + { // Format_RGBA8888_Premultiplied + 0, // Format_Invalid, + 0, // Format_Mono, + 0, // Format_MonoLSB, + 0, // Format_Indexed8, + 0, // Format_RGB32, + 0, // Format_ARGB32, + 0, // Format_ARGB32_Premultiplied, + 0, // Format_RGB16, + 0, // Format_ARGB8565_Premultiplied, + 0, // Format_RGB666, + 0, // Format_ARGB6666_Premultiplied, + 0, // Format_RGB555, + 0, // Format_ARGB8555_Premultiplied, + 0, // Format_RGB888, + 0, // Format_RGB444, + 0, // Format_ARGB4444_Premultiplied, +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + qt_transform_image_rgb32_on_rgb32, // Format_RGBX8888, + 0, // Format_RGBA8888, + qt_transform_image_argb32_on_argb32, // Format_RGBA8888_Premultiplied, +#else + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0 // Format_RGBA8888_Premultiplied, +#endif } }; diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index c79e8babb6..b2108ef67e 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -255,6 +255,33 @@ static const uint *QT_FASTCALL convertFromARGB32PM(uint *buffer, const uint *src return buffer; } +static const uint *QT_FASTCALL convertRGBFromARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *layout, const QRgb *) +{ + Q_ASSERT(layout->redWidth <= 8); + Q_ASSERT(layout->greenWidth <= 8); + Q_ASSERT(layout->blueWidth <= 8); + Q_ASSERT(layout->alphaWidth == 0); + + const uint redMask = (1 << layout->redWidth) - 1; + const uint greenMask = (1 << layout->greenWidth) - 1; + const uint blueMask = (1 << layout->blueWidth) - 1; + + const uchar redRightShift = 24 - layout->redWidth; + const uchar greenRightShift = 16 - layout->greenWidth; + const uchar blueRightShift = 8 - layout->blueWidth; + + for (int i = 0; i < count; ++i) { + uint color = INV_PREMUL(src[i]); + uint red = ((color >> redRightShift) & redMask) << layout->redShift; + uint green = ((color >> greenRightShift) & greenMask) << layout->greenShift; + uint blue = ((color >> blueRightShift) & blueMask) << layout->blueShift; + uint alpha = 0xff << layout->alphaShift; + buffer[i] = red | green | blue | alpha; + } + return buffer; +} + template <QPixelLayout::BPP bpp> static uint QT_FASTCALL fetchPixel(const uchar *src, int index); @@ -386,7 +413,16 @@ QPixelLayout qPixelLayouts[QImage::NImageFormats] = { { 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB8555_Premultiplied { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM }, // Format_RGB888 { 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM }, // Format_RGB444 - { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM } // Format_ARGB4444_Premultiplied + { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB4444_Premultiplied +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + { 8, 24, 8, 16, 8, 8, 0, 0, false, QPixelLayout::BPP32, convertToRGB32, convertRGBFromARGB32PM }, // Format_RGBX8888 + { 8, 24, 8, 16, 8, 8, 8, 0, false, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888 + { 8, 24, 8, 16, 8, 8, 8, 0, true, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888_Premultiplied +#else + { 8, 0, 8, 8, 8, 16, 0, 24, false, QPixelLayout::BPP32, convertToRGB32, convertRGBFromARGB32PM }, // Format_RGBX8888 + { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888 (ABGR32) + { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM } // Format_RGBA8888_Premultiplied +#endif }; FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount] = { @@ -490,7 +526,10 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] = destFetch, // Format_ARGB8555_Premultiplied destFetch, // Format_RGB888 destFetch, // Format_RGB444 - destFetch // Format_ARGB4444_Premultiplied + destFetch, // Format_ARGB4444_Premultiplied + destFetch, // Format_RGBX8888 + destFetch, // Format_RGBA8888 + destFetch, // Format_RGBA8888_Premultiplied }; /* @@ -622,7 +661,10 @@ static DestStoreProc destStoreProc[QImage::NImageFormats] = destStore, // Format_ARGB8555_Premultiplied destStore, // Format_RGB888 destStore, // Format_RGB444 - destStore // Format_ARGB4444_Premultiplied + destStore, // Format_ARGB4444_Premultiplied + destStore, // Format_RGBX8888 + destStore, // Format_RGBA8888 + destStore // Format_RGBA8888_Premultiplied }; /* @@ -1766,7 +1808,10 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { fetchUntransformed, // ARGB8555_Premultiplied fetchUntransformed, // RGB888 fetchUntransformed, // RGB444 - fetchUntransformed // ARGB4444_Premultiplied + fetchUntransformed, // ARGB4444_Premultiplied + fetchUntransformed, // RGBX8888 + fetchUntransformed, // RGBA8888 + fetchUntransformed // RGBA8888_Premultiplied }, // Tiled { @@ -1785,7 +1830,10 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { fetchUntransformed, // ARGB8555_Premultiplied fetchUntransformed, // RGB888 fetchUntransformed, // RGB444 - fetchUntransformed // ARGB4444_Premultiplied + fetchUntransformed, // ARGB4444_Premultiplied + fetchUntransformed, // RGBX8888 + fetchUntransformed, // RGBA8888 + fetchUntransformed // RGBA8888_Premultiplied }, // Transformed { @@ -1805,6 +1853,9 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { fetchTransformed<BlendTransformed>, // RGB888 fetchTransformed<BlendTransformed>, // RGB444 fetchTransformed<BlendTransformed>, // ARGB4444_Premultiplied + fetchTransformed<BlendTransformed>, // RGBX8888 + fetchTransformed<BlendTransformed>, // RGBA8888 + fetchTransformed<BlendTransformed>, // RGBA8888_Premultiplied }, { 0, // TransformedTiled @@ -1823,6 +1874,9 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { fetchTransformed<BlendTransformedTiled>, // RGB888 fetchTransformed<BlendTransformedTiled>, // RGB444 fetchTransformed<BlendTransformedTiled>, // ARGB4444_Premultiplied + fetchTransformed<BlendTransformedTiled>, // RGBX8888 + fetchTransformed<BlendTransformedTiled>, // RGBA8888 + fetchTransformed<BlendTransformedTiled>, // RGBA8888_Premultiplied }, { 0, // Bilinear @@ -1840,7 +1894,10 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB8555_Premultiplied fetchTransformedBilinear<BlendTransformedBilinear>, // RGB888 fetchTransformedBilinear<BlendTransformedBilinear>, // RGB444 - fetchTransformedBilinear<BlendTransformedBilinear> // ARGB4444_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB4444_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinear>, // RGBX8888 + fetchTransformedBilinear<BlendTransformedBilinear>, // RGBA8888 + fetchTransformedBilinear<BlendTransformedBilinear> // RGBA8888_Premultiplied }, { 0, // BilinearTiled @@ -1858,7 +1915,10 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB8555_Premultiplied fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB888 fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB444 - fetchTransformedBilinear<BlendTransformedBilinearTiled> // ARGB4444_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB4444_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGBX8888 + fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGBA8888 + fetchTransformedBilinear<BlendTransformedBilinearTiled> // RGBA8888_Premultiplied }, }; @@ -5268,6 +5328,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats blend_untransformed_generic, blend_untransformed_generic, blend_untransformed_generic, + blend_untransformed_generic, + blend_untransformed_generic, + blend_untransformed_generic, }, // Tiled { @@ -5287,6 +5350,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats blend_tiled_generic, blend_tiled_generic, blend_tiled_generic, + blend_tiled_generic, + blend_tiled_generic, + blend_tiled_generic, }, // Transformed { @@ -5306,6 +5372,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats blend_src_generic, blend_src_generic, blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, }, // TransformedTiled { @@ -5324,6 +5393,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats blend_src_generic, blend_src_generic, blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, blend_src_generic }, // Bilinear @@ -5344,6 +5416,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats blend_src_generic, blend_src_generic, blend_src_generic, + blend_src_generic, + blend_src_generic, + blend_src_generic, }, // BilinearTiled { @@ -5363,6 +5438,9 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats blend_src_generic, // RGB888 blend_src_generic, // RGB444 blend_src_generic, // ARGB4444_Premultiplied + blend_src_generic, // RGBX8888 + blend_src_generic, // RGBA8888 + blend_src_generic, // RGBA8888_Premultiplied } }; @@ -5956,6 +6034,48 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = blend_color_generic, blend_src_generic, 0, 0, 0, 0 + }, + // Format_RGBX8888 + { + blend_color_generic, + qt_gradient_quint32, + qt_bitmapblit_quint32, +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + qt_alphamapblit_quint32, + qt_alphargbblit_quint32, +#else + 0, + 0, +#endif + qt_rectfill_quint32 + }, + // Format_RGBA8888 + { + blend_color_generic, + qt_gradient_quint32, + qt_bitmapblit_quint32, +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + qt_alphamapblit_quint32, + qt_alphargbblit_quint32, +#else + 0, + 0, +#endif + qt_rectfill_quint32 + }, + // Format_RGB8888_Premultiplied + { + blend_color_generic, + qt_gradient_quint32, + qt_bitmapblit_quint32, +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + qt_alphamapblit_quint32, + qt_alphargbblit_quint32, +#else + 0, + 0, +#endif + qt_rectfill_quint32 } }; @@ -6043,6 +6163,9 @@ void qInitDrawhelperAsm() qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_avx; qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_avx; qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_avx; + qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_avx; + qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_avx; + qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_avx; extern void qt_scale_image_argb32_on_argb32_avx(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, @@ -6052,6 +6175,10 @@ void qInitDrawhelperAsm() int const_alpha); qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_avx; qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_avx; +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_avx; + qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_avx; +#endif #endif #ifdef QT_COMPILER_SUPPORTS_SSE2 } else if (features & SSE2) { @@ -6061,6 +6188,9 @@ void qInitDrawhelperAsm() qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2; qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2; qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse2; + qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_sse2; + qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_sse2; + qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2; extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, @@ -6070,6 +6200,10 @@ void qInitDrawhelperAsm() int const_alpha); qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2; qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2; +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2; + qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2; +#endif #endif } @@ -6088,6 +6222,12 @@ void qInitDrawhelperAsm() qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2; + qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2; + qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2; + qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2; +#endif extern const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data, int y, int x, int length); @@ -6104,6 +6244,10 @@ void qInitDrawhelperAsm() qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; + qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; +#endif } #endif // SSSE3 @@ -6122,6 +6266,12 @@ void qInitDrawhelperAsm() qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx; qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx; qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx; +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx; + qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx; + qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx; + qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx; +#endif extern const uint * QT_FASTCALL qt_fetch_radial_gradient_avx(uint *buffer, const Operator *op, const QSpanData *data, int y, int x, int length); @@ -6172,6 +6322,12 @@ void qInitDrawhelperAsm() qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon; qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon; qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon; +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon; + qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon; + qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon; + qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon; +#endif qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon; qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon; diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 0b8a41c904..f4c29996b4 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -653,6 +653,30 @@ static Q_ALWAYS_INLINE uint PREMUL(uint x) { } #endif +#if Q_BYTE_ORDER == Q_BIG_ENDIAN +static Q_ALWAYS_INLINE quint32 RGBA2ARGB(quint32 x) { + quint32 rgb = x >> 8; + quint32 a = x << 24; + return a | rgb; +} + +static Q_ALWAYS_INLINE quint32 ARGB2RGBA(quint32 x) { + quint32 rgb = x << 8; + quint32 a = x >> 24; + return a | rgb; +} +#else +static Q_ALWAYS_INLINE quint32 RGBA2ARGB(quint32 x) { + // RGBA8888 is ABGR32 on little endian. + quint32 ag = x & 0xff00ff00; + quint32 rg = x & 0x00ff00ff; + return ag | (rg << 16) | (rg >> 16); +} + +static Q_ALWAYS_INLINE quint32 ARGB2RGBA(quint32 x) { + return RGBA2ARGB(x); +} +#endif static Q_ALWAYS_INLINE uint BYTE_MUL_RGB16(uint x, uint a) { a += 1; diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp index 27cb08f353..89ccdd42f0 100644 --- a/src/gui/painting/qimagescale.cpp +++ b/src/gui/painting/qimagescale.cpp @@ -1017,7 +1017,7 @@ QImage qSmoothScaleImage(const QImage &src, int dw, int dh) return QImage(); } - if (src.format() == QImage::Format_ARGB32_Premultiplied) + if (src.format() == QImage::Format_ARGB32_Premultiplied || src.format() == QImage::Format_RGBA8888_Premultiplied) qt_qimageScaleArgb(scaleinfo, (unsigned int *)buffer.scanLine(0), 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); else diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp index 747881bbd1..087231df43 100644 --- a/src/gui/painting/qmemrotate.cpp +++ b/src/gui/painting/qmemrotate.cpp @@ -529,7 +529,10 @@ MemRotateFunc qMemRotateFunctions[QImage::NImageFormats][3] = { 0, 0, 0 }, // Format_ARGB8555_Premultiplied, { 0, 0, 0 }, // Format_RGB888, { 0, 0, 0 }, // Format_RGB444, - { 0, 0, 0 } // Format_ARGB4444_Premultiplied, + { 0, 0, 0 }, // Format_ARGB4444_Premultiplied, + { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_RGBX8888, + { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_RGBA8888, + { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 } // Format_RGBA8888_Premultiplied, }; QT_END_NAMESPACE diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index d1e9b81faa..7112380043 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -435,6 +435,8 @@ void QRasterPaintEngine::init() case QImage::Format_ARGB4444_Premultiplied: case QImage::Format_ARGB32_Premultiplied: case QImage::Format_ARGB32: + case QImage::Format_RGBA8888_Premultiplied: + case QImage::Format_RGBA8888: gccaps |= PorterDuff; break; case QImage::Format_RGB32: @@ -443,6 +445,7 @@ void QRasterPaintEngine::init() case QImage::Format_RGB666: case QImage::Format_RGB888: case QImage::Format_RGB16: + case QImage::Format_RGBX8888: break; default: break; @@ -2261,6 +2264,7 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe case QImage::Format_ARGB6666_Premultiplied: case QImage::Format_ARGB8555_Premultiplied: case QImage::Format_ARGB4444_Premultiplied: + case QImage::Format_RGBA8888_Premultiplied: // Combine premultiplied color with the opacity set on the painter. d->solid_color_filler.solid.color = ((((color & 0x00ff00ff) * s->intOpacity) >> 8) & 0x00ff00ff) |