From 5d94aac2bae8bdbf8de7cebeb6a1a17a81685f0a Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 4 Jul 2019 15:17:29 +0200 Subject: [PATCH] Introduce QImage::Format_BGR888 Is pretty common on some architectures so we can avoid swizzling by supporting it. Fixes: QTBUG-45671 Change-Id: Ic7a21b5bfb374bf7496fd2b2b1252c2f1ed47705 Reviewed-by: Eirik Aavitsland --- src/gui/image/qimage.cpp | 15 ++ src/gui/image/qimage.h | 1 + src/gui/image/qimage_conversions.cpp | 222 +++++++++++++----- src/gui/image/qimage_p.h | 1 + src/gui/image/qimage_ssse3.cpp | 7 +- src/gui/image/qpixmap_win.cpp | 3 +- src/gui/image/qpnghandler.cpp | 2 + src/gui/opengl/qopengltextureuploader.cpp | 18 ++ src/gui/painting/qdrawhelper.cpp | 28 ++- .../platforms/linuxfb/qlinuxfbscreen.cpp | 2 +- tests/auto/gui/image/qimage/tst_qimage.cpp | 24 ++ .../image/qimagereader/tst_qimagereader.cpp | 1 + .../gui/painting/qpainter/tst_qpainter.cpp | 1 + .../qimageconversion/tst_qimageconversion.cpp | 22 ++ 14 files changed, 281 insertions(+), 66 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 8e0bbb6907..b7f67cd7ef 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -287,6 +287,7 @@ bool QImageData::checkForAlphaPixels() const case QImage::Format_RGB555: case QImage::Format_RGB666: case QImage::Format_RGB888: + case QImage::Format_BGR888: case QImage::Format_RGBX8888: case QImage::Format_BGR30: case QImage::Format_RGB30: @@ -720,6 +721,7 @@ bool QImageData::checkForAlphaPixels() const \value Format_RGBA64 The image is stored using a 64-bit halfword-ordered RGBA format (16-16-16-16). (added in Qt 5.12) \value Format_RGBA64_Premultiplied The image is stored using a premultiplied 64-bit halfword-ordered RGBA format (16-16-16-16). (added in Qt 5.12) + \value Format_BGR888 The image is stored using a 24-bit BGR format. (added in Qt 5.14) \note Drawing into a QImage with QImage::Format_Indexed8 is not supported. @@ -5550,6 +5552,19 @@ static Q_CONSTEXPR QPixelFormat pixelformats[] = { /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, /*INTERPRETATION*/ QPixelFormat::UnsignedShort, /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_BGR888: + QPixelFormat(QPixelFormat::BGR, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), }; Q_STATIC_ASSERT(sizeof(pixelformats) / sizeof(*pixelformats) == QImage::NImageFormats); diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index 7c68168be8..7544ccca05 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -131,6 +131,7 @@ public: Format_RGBA64, Format_RGBA64_Premultiplied, Format_Grayscale16, + Format_BGR888, #ifndef Q_QDOC NImageFormats #endif diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 837ac88470..539bac222a 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -429,8 +429,8 @@ typedef void (QT_FASTCALL *Rgb888ToRgbConverter)(quint32 *dst, const uchar *src, template static void convert_RGB888_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { - Q_ASSERT(src->format == QImage::Format_RGB888); - if (rgbx) + Q_ASSERT(src->format == QImage::Format_RGB888 || src->format == QImage::Format_BGR888); + if (rgbx ^ (src->format == QImage::Format_BGR888)) Q_ASSERT(dest->format == QImage::Format_RGBX8888 || dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied); else Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied); @@ -1421,6 +1421,69 @@ static void convert_RGBA64_to_gray16(QImageData *dest, const QImageData *src, Qt } } +static void convert_RGB888_to_BGR888(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_RGB888 || src->format == QImage::Format_BGR888); + Q_ASSERT(dest->format == QImage::Format_RGB888 || dest->format == QImage::Format_BGR888); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const qsizetype sbpl = src->bytes_per_line; + const qsizetype dbpl = dest->bytes_per_line; + const uchar *src_data = src->data; + uchar *dest_data = dest->data; + + for (int i = 0; i < src->height; ++i) { + int pixel = 0; + // Handle 4 pixels (12 bytes) at a time + for (; pixel + 3 < src->width; pixel += 4) { + const uchar *src = src_data + pixel * 3; + quint32 *dest_packed = (quint32 *) (dest_data + pixel * 3); + dest_packed[0] = (src[5] << 24) | (src[0] << 16) | (src[1] << 8) | (src[2] << 0); + dest_packed[1] = (src[7] << 24) | (src[8] << 16) | (src[3] << 8) | (src[4] << 0); + dest_packed[2] = (src[9] << 24) | (src[10] << 16) | (src[11] << 8) | (src[6] << 0); + } + + // epilog: handle left over pixels + for (; pixel < src->width; ++pixel) { + dest_data[pixel * 3 + 0] = src_data[pixel * 3 + 2]; + dest_data[pixel * 3 + 1] = src_data[pixel * 3 + 1]; + dest_data[pixel * 3 + 2] = src_data[pixel * 3 + 0]; + } + + src_data += sbpl; + dest_data += dbpl; + } +} + +static bool convert_RGB888_to_BGR888_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_RGB888 || data->format == QImage::Format_BGR888); + + const qsizetype bpl = data->bytes_per_line; + uchar *line_data = data->data; + + for (int i = 0; i < data->height; ++i) { + for (int j = 0; j < data->width; ++j) + qSwap(line_data[j * 3 + 0], line_data[j * 3 + 2]); + line_data += bpl; + } + + switch (data->format) { + case QImage::Format_RGB888: + data->format = QImage::Format_BGR888; + break; + case QImage::Format_BGR888: + data->format = QImage::Format_RGB888; + break; + default: + Q_UNREACHABLE(); + data->format = QImage::Format_Invalid; + return false; + } + return true; +} + static QVector fix_color_table(const QVector &ctbl, QImage::Format format) { QVector colorTable = ctbl; @@ -2265,7 +2328,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, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, @@ -2286,7 +2349,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, 0, 0, 0, 0, 0, 0 }, // Format_Mono { @@ -2308,7 +2371,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, 0, 0, 0, 0, 0, 0 }, // Format_MonoLSB { @@ -2333,7 +2396,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, 0 + 0, 0, 0, 0, 0 }, // Format_Indexed8 { @@ -2361,7 +2424,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_RGB_to_RGB30, 0, 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0 }, // Format_RGB32 { @@ -2391,7 +2454,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, convert_ARGB32_to_RGBA64, - 0, 0 + 0, 0, 0 }, // Format_ARGB32 { @@ -2416,7 +2479,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_ARGB_to_RGBA, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0 }, // Format_ARGB32_Premultiplied { @@ -2438,7 +2501,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, 0, 0, 0, 0, 0, 0 }, // Format_RGB16 { @@ -2460,7 +2523,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, 0, 0, 0, 0, 0, 0 }, // Format_ARGB8565_Premultiplied { @@ -2482,7 +2545,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, 0, 0, 0, 0, 0, 0 }, // Format_RGB666 { @@ -2504,7 +2567,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, 0, 0, 0, 0, 0, 0 }, // Format_ARGB6666_Premultiplied { @@ -2526,7 +2589,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, 0, 0, 0, 0, 0, 0 }, // Format_RGB555 { @@ -2548,7 +2611,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, 0, 0, 0, 0, 0, 0 }, // Format_ARGB8555_Premultiplied { @@ -2565,13 +2628,14 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, + 0, // self 0, 0, convert_RGB888_to_RGB, convert_RGB888_to_RGB, convert_RGB888_to_RGB, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + convert_RGB888_to_BGR888, }, // Format_RGB888 { @@ -2593,7 +2657,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, 0, 0, 0, 0, 0, 0 }, // Format_RGB444 { @@ -2614,7 +2678,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, 0, 0, 0, 0, 0, 0 }, // Format_ARGB4444_Premultiplied { 0, @@ -2641,7 +2705,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_RGB_to_RGB30, 0, 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0 }, // Format_RGBX8888 { 0, @@ -2670,7 +2734,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, convert_ARGB32_to_RGBA64, - 0, 0 + 0, 0, 0 }, // Format_RGBA8888 { @@ -2692,7 +2756,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, 0, 0, 0, 0 }, // Format_RGBA8888_Premultiplied { @@ -2720,7 +2784,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_BGR30_to_RGB30, convert_BGR30_to_RGB30, 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0 }, // Format_BGR30 { 0, @@ -2747,7 +2811,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_A2RGB30_PM_to_RGB30, convert_BGR30_to_RGB30, 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0 }, // Format_A2BGR30_Premultiplied { 0, @@ -2773,7 +2837,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_BGR30_to_RGB30, 0, convert_passthrough, - 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB30 { 0, @@ -2800,7 +2864,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_A2RGB30_PM_to_RGB30, 0, 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0 }, // Format_A2RGB30_Premultiplied { 0, @@ -2820,7 +2884,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, 0, 0, 0, 0, 0, 0 }, // Format_Alpha8 { 0, @@ -2840,14 +2904,15 @@ 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, 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, - convert_RGBA64_to_gray16 + convert_RGBA64_to_gray16, + 0 }, // Format_RGBX64 { 0, @@ -2874,6 +2939,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_RGBA64_to_RGBx64, 0, // self convert_RGBA64_to_RGBA64PM, + 0, 0 }, // Format_RGBA64 { @@ -2901,7 +2967,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_RGBA64PM_to_RGBA64, convert_RGBA64PM_to_RGBA64, 0, // self - convert_RGBA64_to_gray16 + convert_RGBA64_to_gray16, + 0 }, // Format_RGBA64_Premultiplied { 0, @@ -2931,20 +2998,46 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_gray16_to_RGBA64, convert_gray16_to_RGBA64, convert_gray16_to_RGBA64, - 0 // self + 0, // self + 0 }, // Format_Grayscale16 + { + 0, + 0, + 0, + 0, + 0, 0, 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_RGB888_to_BGR888, + 0, + 0, +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + convert_RGB888_to_RGB, + convert_RGB888_to_RGB, + convert_RGB888_to_RGB, +#else + 0, 0, 0, +#endif + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, // self + }, // Format_BGR888 }; 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, 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, 0, 0, 0, 0, 0, 0 }, // Format_MonoLSB { 0, @@ -2968,7 +3061,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, 0 + 0, 0, 0, 0, 0 }, // Format_Indexed8 { 0, @@ -2995,7 +3088,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_RGB_to_RGB30_inplace, 0, 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0 }, // Format_RGB32 { 0, @@ -3022,7 +3115,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_RGB_to_RGB30_inplace, 0, 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0 }, // Format_ARGB32 { 0, @@ -3046,34 +3139,35 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_ARGB_to_RGBA_inplace, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, + convert_RGB888_to_BGR888_inplace }, // 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, 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, 0, 0, 0, 0, 0, 0 }, // Format_ARGB4444_Premultiplied { 0, @@ -3100,7 +3194,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_RGB_to_RGB30_inplace, 0, 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0 }, // Format_RGBX8888 { 0, @@ -3127,7 +3221,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_RGB_to_RGB30_inplace, 0, 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0 }, // Format_RGBA8888 { 0, @@ -3149,7 +3243,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, 0, 0, 0, 0, 0, 0 }, // Format_RGBA8888_Premultiplied { 0, @@ -3176,7 +3270,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_BGR30_to_RGB30_inplace, convert_BGR30_to_A2RGB30_inplace, 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0 }, // Format_BGR30 { 0, @@ -3202,7 +3296,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, // self convert_A2RGB30_PM_to_RGB30_inplace, convert_BGR30_to_RGB30_inplace, - 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }, // Format_A2BGR30_Premultiplied { 0, @@ -3228,7 +3322,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_BGR30_to_A2RGB30_inplace, 0, // self convert_passthrough_inplace, - 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB30 { 0, @@ -3255,7 +3349,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_A2RGB30_PM_to_RGB30_inplace, 0, // self 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0 }, // Format_A2RGB30_Premultiplied { 0, @@ -3280,7 +3374,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, 0, 0, // self 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0 }, // Format_Alpha8 { 0, @@ -3305,32 +3399,37 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, 0, 0, 0, // self - 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_inplace, convert_passthrough_inplace, - 0 + 0, 0 }, // 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, - 0 + 0, 0 }, // 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, convert_RGBA64PM_to_RGBA64_inplace, 0, // self - 0 + 0, 0 }, // Format_RGBA64_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, 0, 0, 0, 0, 0, 0 }, // Format_Grayscale16 + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + convert_RGB888_to_BGR888_inplace, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // Format_BGR888 }; static void qInitImageConversions() @@ -3341,6 +3440,9 @@ static void qInitImageConversions() qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_ssse3; qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_ssse3; qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3; + qimage_converter_map[QImage::Format_BGR888][QImage::Format_RGBX8888] = convert_RGB888_to_RGB32_ssse3; + qimage_converter_map[QImage::Format_BGR888][QImage::Format_RGBA8888] = convert_RGB888_to_RGB32_ssse3; + qimage_converter_map[QImage::Format_BGR888][QImage::Format_RGBA8888_Premultiplied] = convert_RGB888_to_RGB32_ssse3; } #endif diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index 9da6acd0a7..9e2d9c86bb 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -207,6 +207,7 @@ inline int qt_depthForFormat(QImage::Format format) case QImage::Format_ARGB8565_Premultiplied: case QImage::Format_ARGB8555_Premultiplied: case QImage::Format_RGB888: + case QImage::Format_BGR888: depth = 24; break; case QImage::Format_RGBX64: diff --git a/src/gui/image/qimage_ssse3.cpp b/src/gui/image/qimage_ssse3.cpp index 9cdfba20e3..fb81a1a6c3 100644 --- a/src/gui/image/qimage_ssse3.cpp +++ b/src/gui/image/qimage_ssse3.cpp @@ -121,8 +121,11 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, con void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { - Q_ASSERT(src->format == QImage::Format_RGB888); - Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied); + Q_ASSERT(src->format == QImage::Format_RGB888 || src->format == QImage::Format_BGR888); + if (src->format == QImage::Format_BGR888) + Q_ASSERT(dest->format == QImage::Format_RGBX8888 || dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied); + else + Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied); Q_ASSERT(src->width == dest->width); Q_ASSERT(src->height == dest->height); diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp index 3a2db74098..8aad77b991 100644 --- a/src/gui/image/qpixmap_win.cpp +++ b/src/gui/image/qpixmap_win.cpp @@ -281,6 +281,7 @@ Q_GUI_EXPORT HBITMAP qt_imageToWinHBITMAP(const QImage &imageIn, int hbitmapForm } break; case QImage::Format_RGB888: + case QImage::Format_BGR888: compression = BI_RGB; bitCount = 24u; break; @@ -368,7 +369,7 @@ static QImage::Format imageFromWinHBITMAP_Format(const BITMAPINFOHEADER &header, ? QImage::Format_RGB32 : QImage::Format_ARGB32_Premultiplied; break; case 24: - result = QImage::Format_RGB888; + result = QImage::Format_BGR888; break; case 16: result = QImage::Format_RGB555; diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 16d6c25b8b..4ab45337b0 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -1079,6 +1079,7 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i if (color_type == PNG_COLOR_TYPE_RGB) { switch (image.format()) { case QImage::Format_RGB888: + case QImage::Format_BGR888: break; case QImage::Format_RGBX8888: case QImage::Format_RGBX64: @@ -1131,6 +1132,7 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i case QImage::Format_RGB32: case QImage::Format_ARGB32: case QImage::Format_RGB888: + case QImage::Format_BGR888: case QImage::Format_RGBX8888: case QImage::Format_RGBA8888: case QImage::Format_RGBX64: diff --git a/src/gui/opengl/qopengltextureuploader.cpp b/src/gui/opengl/qopengltextureuploader.cpp index d9d5403cf3..9e393bc47a 100644 --- a/src/gui/opengl/qopengltextureuploader.cpp +++ b/src/gui/opengl/qopengltextureuploader.cpp @@ -65,6 +65,10 @@ #define GL_RGBA16 0x805B #endif +#ifndef GL_BGR +#define GL_BGR 0x80E0 +#endif + #ifndef GL_BGRA #define GL_BGRA 0x80E1 #endif @@ -202,6 +206,20 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag pixelType = GL_UNSIGNED_BYTE; targetFormat = QImage::Format_RGB888; break; + case QImage::Format_BGR888: + if (isOpenGL12orBetter) { + externalFormat = GL_BGR; + internalFormat = GL_RGB; + pixelType = GL_UNSIGNED_BYTE; + targetFormat = QImage::Format_BGR888; + } else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) { + funcs->glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_RED); + funcs->glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_BLUE); + externalFormat = internalFormat = GL_RGB; + pixelType = GL_UNSIGNED_BYTE; + targetFormat = QImage::Format_BGR888; + } + break; case QImage::Format_RGBX8888: case QImage::Format_RGBA8888: case QImage::Format_RGBA8888_Premultiplied: diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 55d69221f5..c17bf2ddfd 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -88,6 +88,7 @@ template<> Q_DECL_CONSTEXPR uint redWidth() { return 4; } template<> Q_DECL_CONSTEXPR uint redWidth() { return 5; } template<> Q_DECL_CONSTEXPR uint redWidth() { return 6; } template<> Q_DECL_CONSTEXPR uint redWidth() { return 8; } +template<> Q_DECL_CONSTEXPR uint redWidth() { return 8; } template<> Q_DECL_CONSTEXPR uint redWidth() { return 4; } template<> Q_DECL_CONSTEXPR uint redWidth() { return 5; } template<> Q_DECL_CONSTEXPR uint redWidth() { return 5; } @@ -101,6 +102,7 @@ template<> Q_DECL_CONSTEXPR uint redShift() { return 8; template<> Q_DECL_CONSTEXPR uint redShift() { return 10; } template<> Q_DECL_CONSTEXPR uint redShift() { return 12; } template<> Q_DECL_CONSTEXPR uint redShift() { return 16; } +template<> Q_DECL_CONSTEXPR uint redShift() { return 0; } template<> Q_DECL_CONSTEXPR uint redShift() { return 8; } template<> Q_DECL_CONSTEXPR uint redShift() { return 18; } template<> Q_DECL_CONSTEXPR uint redShift() { return 19; } @@ -119,6 +121,7 @@ template<> Q_DECL_CONSTEXPR uint greenWidth() { return 4; template<> Q_DECL_CONSTEXPR uint greenWidth() { return 5; } template<> Q_DECL_CONSTEXPR uint greenWidth() { return 6; } template<> Q_DECL_CONSTEXPR uint greenWidth() { return 8; } +template<> Q_DECL_CONSTEXPR uint greenWidth() { return 8; } template<> Q_DECL_CONSTEXPR uint greenWidth() { return 4; } template<> Q_DECL_CONSTEXPR uint greenWidth() { return 5; } template<> Q_DECL_CONSTEXPR uint greenWidth() { return 6; } @@ -132,6 +135,7 @@ template<> Q_DECL_CONSTEXPR uint greenShift() { return 4; template<> Q_DECL_CONSTEXPR uint greenShift() { return 5; } template<> Q_DECL_CONSTEXPR uint greenShift() { return 6; } template<> Q_DECL_CONSTEXPR uint greenShift() { return 8; } +template<> Q_DECL_CONSTEXPR uint greenShift() { return 8; } template<> Q_DECL_CONSTEXPR uint greenShift() { return 4; } template<> Q_DECL_CONSTEXPR uint greenShift() { return 13; } template<> Q_DECL_CONSTEXPR uint greenShift() { return 13; } @@ -150,6 +154,7 @@ template<> Q_DECL_CONSTEXPR uint blueWidth() { return 4; template<> Q_DECL_CONSTEXPR uint blueWidth() { return 5; } template<> Q_DECL_CONSTEXPR uint blueWidth() { return 6; } template<> Q_DECL_CONSTEXPR uint blueWidth() { return 8; } +template<> Q_DECL_CONSTEXPR uint blueWidth() { return 8; } template<> Q_DECL_CONSTEXPR uint blueWidth() { return 4; } template<> Q_DECL_CONSTEXPR uint blueWidth() { return 5; } template<> Q_DECL_CONSTEXPR uint blueWidth() { return 5; } @@ -163,6 +168,7 @@ template<> Q_DECL_CONSTEXPR uint blueShift() { return 0; template<> Q_DECL_CONSTEXPR uint blueShift() { return 0; } template<> Q_DECL_CONSTEXPR uint blueShift() { return 0; } template<> Q_DECL_CONSTEXPR uint blueShift() { return 0; } +template<> Q_DECL_CONSTEXPR uint blueShift() { return 16; } template<> Q_DECL_CONSTEXPR uint blueShift() { return 0; } template<> Q_DECL_CONSTEXPR uint blueShift() { return 8; } template<> Q_DECL_CONSTEXPR uint blueShift() { return 8; } @@ -181,6 +187,7 @@ template<> Q_DECL_CONSTEXPR uint alphaWidth() { return 0; template<> Q_DECL_CONSTEXPR uint alphaWidth() { return 0; } template<> Q_DECL_CONSTEXPR uint alphaWidth() { return 0; } template<> Q_DECL_CONSTEXPR uint alphaWidth() { return 0; } +template<> Q_DECL_CONSTEXPR uint alphaWidth() { return 0; } template<> Q_DECL_CONSTEXPR uint alphaWidth() { return 4; } template<> Q_DECL_CONSTEXPR uint alphaWidth() { return 8; } template<> Q_DECL_CONSTEXPR uint alphaWidth() { return 8; } @@ -194,6 +201,7 @@ template<> Q_DECL_CONSTEXPR uint alphaShift() { return 0; template<> Q_DECL_CONSTEXPR uint alphaShift() { return 0; } template<> Q_DECL_CONSTEXPR uint alphaShift() { return 0; } template<> Q_DECL_CONSTEXPR uint alphaShift() { return 0; } +template<> Q_DECL_CONSTEXPR uint alphaShift() { return 0; } template<> Q_DECL_CONSTEXPR uint alphaShift() { return 12; } template<> Q_DECL_CONSTEXPR uint alphaShift() { return 0; } template<> Q_DECL_CONSTEXPR uint alphaShift() { return 0; } @@ -214,6 +222,7 @@ template<> constexpr QPixelLayout::BPP bitsPerPixel() { r template<> constexpr QPixelLayout::BPP bitsPerPixel() { return QPixelLayout::BPP16; } template<> constexpr QPixelLayout::BPP bitsPerPixel() { return QPixelLayout::BPP24; } template<> constexpr QPixelLayout::BPP bitsPerPixel() { return QPixelLayout::BPP24; } +template<> constexpr QPixelLayout::BPP bitsPerPixel() { return QPixelLayout::BPP24; } template<> constexpr QPixelLayout::BPP bitsPerPixel() { return QPixelLayout::BPP16; } template<> constexpr QPixelLayout::BPP bitsPerPixel() { return QPixelLayout::BPP24; } template<> constexpr QPixelLayout::BPP bitsPerPixel() { return QPixelLayout::BPP24; } @@ -1528,7 +1537,8 @@ QPixelLayout qPixelLayouts[QImage::NImageFormats] = { { false, false, QPixelLayout::BPP16, nullptr, convertGrayscale16ToRGB32, convertGrayscale16ToRGBA64, fetchGrayscale16ToRGB32, fetchGrayscale16ToRGBA64, - storeGrayscale16FromARGB32PM, storeGrayscale16FromRGB32 } // Format_Grayscale16 + storeGrayscale16FromARGB32PM, storeGrayscale16FromRGB32 }, // Format_Grayscale16 + pixelLayoutRGB(), }; Q_STATIC_ASSERT(sizeof(qPixelLayouts) / sizeof(*qPixelLayouts) == QImage::NImageFormats); @@ -1643,7 +1653,8 @@ ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[QImage::NImageFormats] = { storeRGBX64FromRGBA64PM, storeRGBA64FromRGBA64PM, storeRGBA64PMFromRGBA64PM, - storeGray16FromRGBA64PM + storeGray16FromRGBA64PM, + storeGenericFromRGBA64PM, }; /* @@ -1732,6 +1743,7 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] = destFetch, // Format_RGBA64 destFetch, // Format_RGBA64_Premultiplied destFetch, // Format_Grayscale16 + destFetch, // Format_BGR888 }; #if QT_CONFIG(raster_64bit) @@ -1782,6 +1794,7 @@ static DestFetchProc64 destFetchProc64[QImage::NImageFormats] = destFetch64, // Format_RGBA64 destFetchRGB64, // Format_RGBA64_Premultiplied destFetch64, // Format_Grayscale16 + destFetch64, // Format_BGR888 }; #endif @@ -1922,6 +1935,7 @@ static DestStoreProc destStoreProc[QImage::NImageFormats] = destStore, // Format_RGBA64 destStore, // Format_RGBA64_Premultiplied destStore, // Format_Grayscale16 + destStore, // Format_BGR888 }; #if QT_CONFIG(raster_64bit) @@ -1971,6 +1985,7 @@ static DestStoreProc64 destStoreProc64[QImage::NImageFormats] = destStore64RGBA64, // Format_RGBA64 0, // Format_RGBA64_Premultiplied destStore64, // Format_Grayscale16 + destStore64, // Format_BGR888 }; #endif @@ -3922,6 +3937,7 @@ static SourceFetchProc sourceFetchUntransformed[QImage::NImageFormats] = { fetchUntransformed, // RGBA64 fetchUntransformed, // RGBA64_Premultiplied fetchUntransformed, // Grayscale16 + fetchUntransformed, // BGR888 }; static const SourceFetchProc sourceFetchGeneric[NBlendTypes] = { @@ -6589,6 +6605,14 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = qt_alphargbblit_generic, qt_rectfill_quint16 }, + // Format_BGR888 + { + blend_color_generic, + 0, + qt_alphamapblit_generic, + qt_alphargbblit_generic, + qt_rectfill_quint24 + }, }; #if !defined(__SSE2__) diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp index dc7ea08dc5..cb8962d4b8 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp @@ -188,7 +188,7 @@ static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth) if (memcmp(rgba, rgb888, 3 * sizeof(fb_bitfield)) == 0) { format = QImage::Format_RGB888; } else if (memcmp(rgba, bgr888, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB888; + format = QImage::Format_BGR888; // pixeltype = BGRPixel; } break; diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 441ec17412..b84aa52465 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -303,6 +303,8 @@ static QLatin1String formatToString(QImage::Format format) return QLatin1String("RGBA64pm"); case QImage::Format_Grayscale16: return QLatin1String("Grayscale16"); + case QImage::Format_BGR888: + return QLatin1String("BGR888"); default: break; }; @@ -844,6 +846,13 @@ void tst_QImage::convertToFormat_data() QTest::newRow("blue rgb32 -> rgb888") << int(QImage::Format_RGB32) << 0xff0000ff << int(QImage::Format_RGB888) << 0xff0000ff; + QTest::newRow("red rgb32 -> bgr888") << int(QImage::Format_RGB32) << 0xffff0000 + << int(QImage::Format_BGR888) << 0xffff0000; + QTest::newRow("green rgb32 -> bgr888") << int(QImage::Format_RGB32) << 0xff00ff00 + << int(QImage::Format_BGR888) << 0xff00ff00; + QTest::newRow("blue rgb32 -> bgr888") << int(QImage::Format_RGB32) << 0xff0000ff + << int(QImage::Format_BGR888) << 0xff0000ff; + QTest::newRow("red rgb16 -> rgb888") << int(QImage::Format_RGB16) << 0xffff0000 << int(QImage::Format_RGB888) << 0xffff0000; QTest::newRow("green rgb16 -> rgb888") << int(QImage::Format_RGB16) << 0xff00ff00 @@ -858,6 +867,13 @@ void tst_QImage::convertToFormat_data() QTest::newRow("blue rgb888 -> argb32") << int(QImage::Format_RGB888) << 0xff0000ff << int(QImage::Format_ARGB32) << 0xff0000ff; + QTest::newRow("red bgr888 -> argb32") << int(QImage::Format_RGB888) << 0xffff0000 + << int(QImage::Format_ARGB32) << 0xffff0000; + QTest::newRow("green bgr888 -> argb32") << int(QImage::Format_RGB888) << 0xff00ff00 + << int(QImage::Format_ARGB32) << 0xff00ff00; + QTest::newRow("blue bgr888 -> argb32") << int(QImage::Format_RGB888) << 0xff0000ff + << int(QImage::Format_ARGB32) << 0xff0000ff; + QTest::newRow("red rgb888 -> rgbx8888") << int(QImage::Format_RGB888) << 0xffff0000 << int(QImage::Format_RGBX8888) << 0xffff0000; QTest::newRow("green rgb888 -> rgbx8888") << int(QImage::Format_RGB888) << 0xff00ff00 @@ -1338,6 +1354,12 @@ void tst_QImage::setPixel_data() << 0xff00ff00 << 0x00ff00u; QTest::newRow("RGB888 blue") << int(QImage::Format_RGB888) << 0xff0000ff << 0x0000ffu; + QTest::newRow("BGR888 red") << int(QImage::Format_BGR888) + << 0xffff0000 << 0x0000ffu; + QTest::newRow("BGR888 green") << int(QImage::Format_BGR888) + << 0xff00ff00 << 0x00ff00u; + QTest::newRow("BGR888 blue") << int(QImage::Format_BGR888) + << 0xff0000ff << 0xff0000u; #if Q_BYTE_ORDER == Q_BIG_ENDIAN QTest::newRow("RGBA8888 red") << int(QImage::Format_RGBA8888) << 0xffff0000u << 0xff0000ffu; @@ -1425,6 +1447,7 @@ void tst_QImage::setPixel() case int(QImage::Format_ARGB8565_Premultiplied): case int(QImage::Format_ARGB8555_Premultiplied): case int(QImage::Format_RGB888): + case int(QImage::Format_BGR888): { for (int y = 0; y < h; ++y) { const quint24 *row = (const quint24*)(img.scanLine(y)); @@ -2445,6 +2468,7 @@ void tst_QImage::mirrored_data() QTest::newRow("Format_RGB555, vertical") << QImage::Format_RGB555 << true << false << 16 << 16; QTest::newRow("Format_ARGB8555_Premultiplied, vertical") << QImage::Format_ARGB8555_Premultiplied << true << false << 16 << 16; QTest::newRow("Format_RGB888, vertical") << QImage::Format_RGB888 << true << false << 16 << 16; + QTest::newRow("Format_BGR888, vertical") << QImage::Format_BGR888 << true << false << 16 << 16; QTest::newRow("Format_RGB444, vertical") << QImage::Format_RGB444 << true << false << 16 << 16; QTest::newRow("Format_RGBX8888, vertical") << QImage::Format_RGBX8888 << true << false << 16 << 16; QTest::newRow("Format_RGBA8888_Premultiplied, vertical") << QImage::Format_RGBA8888_Premultiplied << true << false << 16 << 16; diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp index eeabfd0413..f6ffd7b7c5 100644 --- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp @@ -1863,6 +1863,7 @@ void tst_QImageReader::saveFormat_data() QTest::newRow("Format_RGB555") << QImage::Format_RGB555; QTest::newRow("Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied; QTest::newRow("Format_RGB888") << QImage::Format_RGB888; + QTest::newRow("Format_BGR888") << QImage::Format_BGR888; QTest::newRow("Format_RGB444") << QImage::Format_RGB444; QTest::newRow("Format_ARGB4444_Premultiplied") << QImage::Format_ARGB4444_Premultiplied; QTest::newRow("Format_RGBA64") << QImage::Format_RGBA64; diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 0efeb9b356..61867ec65a 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -1637,6 +1637,7 @@ void tst_QPainter::qimageFormats_data() QTest::newRow("Qimage::Format_RGB555") << QImage::Format_RGB555; QTest::newRow("Qimage::Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied; QTest::newRow("Qimage::Format_RGB888") << QImage::Format_RGB888; + QTest::newRow("Qimage::Format_BGR888") << QImage::Format_BGR888; QTest::newRow("Qimage::Format_A2RGB30_Premultiplied") << QImage::Format_A2RGB30_Premultiplied; QTest::newRow("Qimage::Format_RGB30") << QImage::Format_RGB30; } diff --git a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp index 570c7b59fa..b88669e9ce 100644 --- a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp +++ b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp @@ -183,6 +183,7 @@ void tst_QImageConversion::convertRgb32_data() QTest::newRow("rgb32 -> rgb30") << rgb32 << QImage::Format_RGB30; QTest::newRow("rgb32 -> a2bgr30") << rgb32 << QImage::Format_A2BGR30_Premultiplied; QTest::newRow("rgb32 -> rgb888") << rgb32 << QImage::Format_RGB888; + QTest::newRow("rgb32 -> bgr888") << rgb32 << QImage::Format_BGR888; QTest::newRow("rgb32 -> rgb666") << rgb32 << QImage::Format_RGB666; QTest::newRow("rgb32 -> rgb555") << rgb32 << QImage::Format_RGB555; QTest::newRow("rgb32 -> argb8565pm") << rgb32 << QImage::Format_ARGB8565_Premultiplied; @@ -196,6 +197,7 @@ void tst_QImageConversion::convertRgb32_data() QTest::newRow("argb32 -> rgb30") << argb32 << QImage::Format_RGB30; QTest::newRow("argb32 -> a2bgr30") << argb32 << QImage::Format_A2BGR30_Premultiplied; QTest::newRow("argb32 -> rgb888") << argb32 << QImage::Format_RGB888; + QTest::newRow("argb32 -> bgr888") << argb32 << QImage::Format_BGR888; QTest::newRow("argb32 -> rgb666") << argb32 << QImage::Format_RGB666; QTest::newRow("argb32 -> argb8565pm") << argb32 << QImage::Format_ARGB8565_Premultiplied; QTest::newRow("argb32 -> argb4444pm") << argb32 << QImage::Format_ARGB4444_Premultiplied; @@ -212,6 +214,7 @@ void tst_QImageConversion::convertRgb32_data() QTest::newRow("argb32pm -> rgb30") << argb32pm << QImage::Format_RGB30; QTest::newRow("argb32pm -> a2bgr30") << argb32pm << QImage::Format_A2BGR30_Premultiplied; QTest::newRow("argb32pm -> rgb888") << argb32pm << QImage::Format_RGB888; + QTest::newRow("argb32pm -> bgr888") << argb32pm << QImage::Format_BGR888; QTest::newRow("argb32pm -> rgb666") << argb32pm << QImage::Format_RGB666; QTest::newRow("argb32pm -> argb8565pm") << argb32pm << QImage::Format_ARGB8565_Premultiplied; QTest::newRow("argb32pm -> argb4444pm") << argb32pm << QImage::Format_ARGB4444_Premultiplied; @@ -242,6 +245,8 @@ void tst_QImageConversion::convertGeneric_data() QImage rgb666 = rgb32.convertToFormat(QImage::Format_RGB666); QImage argb4444 = argb32.convertToFormat(QImage::Format_ARGB4444_Premultiplied); QImage rgba64pm = argb32.convertToFormat(QImage::Format_RGBA64_Premultiplied); + QImage rgb888 = rgb32.convertToFormat(QImage::Format_RGB888); + QImage bgr888 = rgb32.convertToFormat(QImage::Format_BGR888); QTest::newRow("indexed8 -> rgb32") << i8 << QImage::Format_RGB32; QTest::newRow("indexed8 -> argb32") << i8 << QImage::Format_ARGB32; @@ -299,6 +304,20 @@ void tst_QImageConversion::convertGeneric_data() QTest::newRow("rgba64pm -> rgb30") << rgba64pm << QImage::Format_RGB30; QTest::newRow("rgba64pm -> a2bgr30") << rgba64pm << QImage::Format_A2BGR30_Premultiplied; QTest::newRow("rgba64pm -> rgba64") << rgba64pm << QImage::Format_RGBA64; + + QTest::newRow("rgb888 -> rgb32") << rgb888 << QImage::Format_RGB32; + QTest::newRow("rgb888 -> argb32") << rgb888 << QImage::Format_ARGB32; + QTest::newRow("rgb888 -> argb32pm") << rgb888 << QImage::Format_ARGB32_Premultiplied; + QTest::newRow("rgb888 -> rgbx8888") << rgb888 << QImage::Format_RGBX8888; + QTest::newRow("rgb888 -> rgba8888pm") << rgb888 << QImage::Format_RGBA8888_Premultiplied; + QTest::newRow("rgb888 -> bgr888") << rgb888 << QImage::Format_BGR888; + + QTest::newRow("bgr888 -> rgb32") << bgr888 << QImage::Format_RGB32; + QTest::newRow("bgr888 -> argb32") << bgr888 << QImage::Format_ARGB32; + QTest::newRow("bgr888 -> argb32pm") << bgr888 << QImage::Format_ARGB32_Premultiplied; + QTest::newRow("bgr888 -> rgbx8888") << bgr888 << QImage::Format_RGBX8888; + QTest::newRow("bgr888 -> rgba8888pm") << bgr888 << QImage::Format_RGBA8888_Premultiplied; + QTest::newRow("bgr888 -> rgb888") << bgr888 << QImage::Format_RGB888; } void tst_QImageConversion::convertGeneric() @@ -323,6 +342,7 @@ void tst_QImageConversion::convertGenericInplace_data() QImage argb6666 = argb32.convertToFormat(QImage::Format_ARGB6666_Premultiplied); QImage argb4444 = argb32.convertToFormat(QImage::Format_ARGB4444_Premultiplied); QImage rgb16 = argb32.convertToFormat(QImage::Format_RGB16); + QImage rgb888 = argb32.convertToFormat(QImage::Format_RGB888); QTest::newRow("argb32 -> argb32pm -> argb32") << argb32 << QImage::Format_ARGB32_Premultiplied; QTest::newRow("argb32 -> rgb32 -> argb32") << argb32 << QImage::Format_RGB32; @@ -349,6 +369,8 @@ void tst_QImageConversion::convertGenericInplace_data() QTest::newRow("rgb16 -> rgb555 -> rgb16") << rgb16 << QImage::Format_RGB555; QTest::newRow("rgb16 -> rgb444 -> rgb16") << rgb16 << QImage::Format_RGB444; QTest::newRow("rgb16 -> argb4444pm -> rgb16") << rgb16 << QImage::Format_ARGB4444_Premultiplied; + + QTest::newRow("rgb888 -> bgr888 -> rgb888") << rgb888 << QImage::Format_BGR888; } void tst_QImageConversion::convertGenericInplace()