diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2014-05-26 12:07:18 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2014-07-04 14:03:46 +0200 |
commit | 3acd4b546ded7523f65d60cee6f3809113a91a16 (patch) | |
tree | ac526a90c4b39229ea5ec4c80b779ca8a4b66c24 | |
parent | 715b41ce48c9dd78eec3223606e9ca5193cf5bad (diff) |
QImage support for RGB30 formats
Adds basic support for 10-bit per color channel formats to QImage
and the XCB plugin. This will make it possible to paint to and from
these formats, but only at 8-bit per color channel accuracy.
This also fixes Qt5 applications on X11 with native 30bit depth.
[ChangeLog][QtGui][QImage] Added support for 10-bit per color channel image formats.
Task-number: QTBUG-25998
Change-Id: I93ccd3c74bfbb0bd94b352476e5fe58a94119e1f
Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com>
-rw-r--r-- | src/gui/image/qbmphandler.cpp | 4 | ||||
-rw-r--r-- | src/gui/image/qimage.cpp | 147 | ||||
-rw-r--r-- | src/gui/image/qimage.h | 4 | ||||
-rw-r--r-- | src/gui/image/qimage_conversions.cpp | 603 | ||||
-rw-r--r-- | src/gui/image/qimage_p.h | 6 | ||||
-rw-r--r-- | src/gui/image/qpixmap.cpp | 3 | ||||
-rw-r--r-- | src/gui/image/qppmhandler.cpp | 4 | ||||
-rw-r--r-- | src/gui/painting/qblendfunctions.cpp | 809 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 147 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper_p.h | 117 | ||||
-rw-r--r-- | src/gui/painting/qmemrotate.cpp | 5 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 6 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbimage.cpp | 15 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 43 | ||||
-rw-r--r-- | tests/auto/gui/image/qimage/tst_qimage.cpp | 31 | ||||
-rw-r--r-- | tests/auto/gui/painting/qpainter/tst_qpainter.cpp | 28 |
16 files changed, 1847 insertions, 125 deletions
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index bb79a139b3..036d0615e3 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -798,6 +798,8 @@ bool QBmpHandler::write(const QImage &img) case QImage::Format_ARGB4444_Premultiplied: case QImage::Format_RGBA8888: case QImage::Format_RGBA8888_Premultiplied: + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_A2RGB30_Premultiplied: image = img.convertToFormat(QImage::Format_ARGB32); break; case QImage::Format_RGB16: @@ -806,6 +808,8 @@ bool QBmpHandler::write(const QImage &img) case QImage::Format_RGB555: case QImage::Format_RGB444: case QImage::Format_RGBX8888: + case QImage::Format_BGR30: + case QImage::Format_RGB30: image = img.convertToFormat(QImage::Format_RGB32); break; default: diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index b0b6b27b71..d8c3a8c2eb 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -222,6 +222,16 @@ bool QImageData::checkForAlphaPixels() const } } break; + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_A2RGB30_Premultiplied: { + uchar *bits = data; + for (int y=0; y<height && !has_alpha_pixels; ++y) { + for (int x=0; x<width; ++x) + has_alpha_pixels |= (((uint *)bits)[x] & 0xc0000000) != 0xc0000000; + bits += bytes_per_line; + } + } break; + case QImage::Format_ARGB8555_Premultiplied: case QImage::Format_ARGB8565_Premultiplied: { uchar *bits = data; @@ -701,6 +711,10 @@ bool QImageData::checkForAlphaPixels() const 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). + \value Format_BGR30 The image is stored using a 32-bit BGR format (x-10-10-10). + \value Format_A2BGR30_Premultiplied The image is stored using a 32-bit premultiplied ABGR format (2-10-10-10). + \value Format_RGB30 The image is stored using a 32-bit RGB format (x-10-10-10). + \value Format_A2RGB30_Premultiplied The image is stored using a 32-bit premultiplied ARGB format (2-10-10-10). \note Drawing into a QImage with QImage::Format_Indexed8 is not supported. @@ -708,6 +722,9 @@ bool QImageData::checkForAlphaPixels() const \note Do not render into ARGB32 images using QPainter. Using QImage::Format_ARGB32_Premultiplied is significantly faster. + \note Formats with more than 8 bit per color channel will only be processed by the raster engine using 8 bit + per color. + \sa format(), convertToFormat() */ @@ -1670,6 +1687,8 @@ void QImage::fill(uint pixel) #else pixel |= 0x000000ff; #endif + if (d->format == Format_BGR30 || d->format == Format_RGB30) + pixel |= 0xc0000000; qt_rectfill<uint>(reinterpret_cast<uint*>(d->data), pixel, 0, 0, d->width, d->height, d->bytes_per_line); @@ -1736,6 +1755,14 @@ void QImage::fill(const QColor &color) case QImage::Format_RGBA8888_Premultiplied: fill(ARGB2RGBA(qPremultiply(color.rgba()))); break; + case QImage::Format_BGR30: + case QImage::Format_A2BGR30_Premultiplied: + fill(qConvertArgb32ToA2rgb30<PixelOrderBGR>(color.rgba())); + break; + case QImage::Format_RGB30: + case QImage::Format_A2RGB30_Premultiplied: + fill(qConvertArgb32ToA2rgb30<PixelOrderRGB>(color.rgba())); + break; case QImage::Format_RGB16: fill((uint) qConvertRgb32To16(color.rgba())); break; @@ -2142,6 +2169,12 @@ QRgb QImage::pixel(int x, int y) const case Format_RGBA8888: // Match ARGB32 behavior. case Format_RGBA8888_Premultiplied: return RGBA2ARGB(reinterpret_cast<const quint32 *>(s)[x]); + case Format_BGR30: + case Format_A2BGR30_Premultiplied: + return qConvertA2rgb30ToArgb32<PixelOrderBGR>(reinterpret_cast<const quint32 *>(s)[x]); + case Format_RGB30: + case Format_A2RGB30_Premultiplied: + return qConvertA2rgb30ToArgb32<PixelOrderRGB>(reinterpret_cast<const quint32 *>(s)[x]); case Format_RGB16: return qConvertRgb16To32(reinterpret_cast<const quint16 *>(s)[x]); default: @@ -2232,6 +2265,18 @@ void QImage::setPixel(int x, int y, uint index_or_rgb) case Format_RGBA8888_Premultiplied: ((uint *)s)[x] = ARGB2RGBA(index_or_rgb); return; + case Format_BGR30: + ((uint *)s)[x] = qConvertRgb32ToRgb30<PixelOrderBGR>(index_or_rgb); + return; + case Format_A2BGR30_Premultiplied: + ((uint *)s)[x] = qConvertArgb32ToA2rgb30<PixelOrderBGR>(index_or_rgb); + return; + case Format_RGB30: + ((uint *)s)[x] = qConvertRgb32ToRgb30<PixelOrderRGB>(index_or_rgb); + return; + case Format_A2RGB30_Premultiplied: + ((uint *)s)[x] = qConvertArgb32ToA2rgb30<PixelOrderRGB>(index_or_rgb); + return; case Format_Invalid: case NImageFormats: Q_ASSERT(false); @@ -2959,6 +3004,23 @@ QImage QImage::rgbSwapped_helper() const } } break; + case Format_BGR30: + case Format_A2BGR30_Premultiplied: + case Format_RGB30: + case Format_A2RGB30_Premultiplied: + res = QImage(d->width, d->height, d->format); + QIMAGE_SANITYCHECK_MEMORY(res); + for (int i = 0; i < d->height; i++) { + uint *q = (uint*)res.scanLine(i); + const uint *p = (const uint*)constScanLine(i); + const uint *end = p + d->width; + while (p < end) { + *q = qRgbSwapRgb30(*p); + p++; + q++; + } + } + break; default: res = QImage(d->width, d->height, d->format); rgbSwapped_generic(d->width, d->height, this, &res, &qPixelLayouts[d->format]); @@ -3019,6 +3081,19 @@ void QImage::rgbSwapped_inplace() } } break; + case Format_BGR30: + case Format_A2BGR30_Premultiplied: + case Format_RGB30: + case Format_A2RGB30_Premultiplied: + for (int i = 0; i < d->height; i++) { + uint *p = (uint*)scanLine(i); + uint *end = p + d->width; + while (p < end) { + *p = qRgbSwapRgb30(*p); + p++; + } + } + break; default: rgbSwapped_generic(d->width, d->height, this, this, &qPixelLayouts[d->format]); break; @@ -4044,6 +4119,8 @@ bool QImage::hasAlphaChannel() const || d->format == Format_ARGB4444_Premultiplied || d->format == Format_RGBA8888 || d->format == Format_RGBA8888_Premultiplied + || d->format == Format_A2BGR30_Premultiplied + || d->format == Format_A2RGB30_Premultiplied || (d->has_alpha_clut && (d->format == Format_Indexed8 || d->format == Format_Mono || d->format == Format_MonoLSB))); @@ -4069,6 +4146,10 @@ int QImage::bitPlaneCount() const switch (d->format) { case QImage::Format_Invalid: break; + case QImage::Format_BGR30: + case QImage::Format_RGB30: + bpc = 30; + break; case QImage::Format_RGB32: case QImage::Format_RGBX8888: bpc = 24; @@ -4122,6 +4203,10 @@ static QImage rotated90(const QImage &image) { case QImage::Format_RGBX8888: case QImage::Format_RGBA8888: case QImage::Format_RGBA8888_Premultiplied: + case QImage::Format_BGR30: + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_RGB30: + case QImage::Format_A2RGB30_Premultiplied: qt_memrotate270(reinterpret_cast<const quint32*>(image.bits()), w, h, image.bytesPerLine(), reinterpret_cast<quint32*>(out.bits()), @@ -4184,6 +4269,10 @@ static QImage rotated270(const QImage &image) { case QImage::Format_RGBX8888: case QImage::Format_RGBA8888: case QImage::Format_RGBA8888_Premultiplied: + case QImage::Format_BGR30: + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_RGB30: + case QImage::Format_A2RGB30_Premultiplied: qt_memrotate90(reinterpret_cast<const quint32*>(image.bits()), w, h, image.bytesPerLine(), reinterpret_cast<quint32*>(out.bits()), @@ -4332,6 +4421,12 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode case QImage::Format_RGBX8888: target_format = Format_RGBA8888_Premultiplied; break; + case QImage::Format_BGR30: + target_format = Format_A2BGR30_Premultiplied; + break; + case QImage::Format_RGB30: + target_format = Format_A2RGB30_Premultiplied; + break; default: target_format = Format_ARGB32_Premultiplied; break; @@ -4741,6 +4836,58 @@ static const QPixelFormat pixelformats[] = { /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, /*INTERPRETATION*/ QPixelFormat::UnsignedByte, /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_BGR30: + QPixelFormat(QPixelFormat::BGR, + /*RED*/ 10, + /*GREEN*/ 10, + /*BLUE*/ 10, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 2, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_A2BGR30_Premultiplied: + QPixelFormat(QPixelFormat::BGR, + /*RED*/ 10, + /*GREEN*/ 10, + /*BLUE*/ 10, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 2, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB30: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 10, + /*GREEN*/ 10, + /*BLUE*/ 10, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 2, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_A2RGB30_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 10, + /*GREEN*/ 10, + /*BLUE*/ 10, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 2, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*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 365a7873a4..62f9f5cce2 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -124,6 +124,10 @@ public: Format_Grayscale2, Format_Grayscale2LSB #endif + Format_BGR30, + Format_A2BGR30_Premultiplied, + Format_RGB30, + Format_A2RGB30_Premultiplied, #ifndef Q_QDOC NImageFormats #endif diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 11c4b6d504..195b56afbe 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -172,6 +172,35 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im return true; } +static void convert_passthrough(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + 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 = *src_data; + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template<QImage::Format Format> +static bool convert_passthrough_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + data->format = Format; + return true; +} + static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888); @@ -404,6 +433,292 @@ static bool convert_RGBA_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversio return true; } +template<QtPixelOrder PixelOrder> +static void convert_RGB_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + + Q_ASSERT(src->format == QImage::Format_RGB32 || src->format == QImage::Format_ARGB32); + Q_ASSERT(dest->format == QImage::Format_BGR30 || dest->format == QImage::Format_A2BGR30_Premultiplied + || dest->format == QImage::Format_RGB30 || dest->format == QImage::Format_A2RGB30_Premultiplied); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const int src_pad = (src->bytes_per_line >> 2) - src->width; + const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; + const quint32 *src_data = (quint32 *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + const quint32 *end = src_data + src->width; + while (src_data < end) { + *dest_data = qConvertRgb32ToRgb30<PixelOrder>(*src_data); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template<QtPixelOrder PixelOrder> +static void convert_RGB30_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_BGR30 || src->format == QImage::Format_RGB30); + 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); + + const int src_pad = (src->bytes_per_line >> 2) - src->width; + const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; + const quint32 *src_data = (quint32 *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + const quint32 *end = src_data + src->width; + while (src_data < end) { + *dest_data = qConvertA2rgb30ToArgb32<PixelOrder>(*src_data); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template<QtPixelOrder PixelOrder> +static void convert_A2RGB30_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_A2RGB30_Premultiplied || src->format == QImage::Format_A2BGR30_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_RGB32); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const int src_pad = (src->bytes_per_line >> 2) - src->width; + const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; + const quint32 *src_data = (quint32 *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + const quint32 *end = src_data + src->width; + while (src_data < end) { + *dest_data = 0xff000000 | qUnpremultiply(qConvertA2rgb30ToArgb32<PixelOrder>(*src_data)); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template<QtPixelOrder PixelOrder> +static void convert_ARGB_PM_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_BGR30 || dest->format == QImage::Format_RGB30); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const int src_pad = (src->bytes_per_line >> 2) - src->width; + const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; + const quint32 *src_data = (quint32 *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + const quint32 *end = src_data + src->width; + while (src_data < end) { + *dest_data = qConvertRgb32ToRgb30<PixelOrder>(qUnpremultiply(*src_data)); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template<QtPixelOrder PixelOrder> +static void convert_ARGB_to_A2RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_A2BGR30_Premultiplied || dest->format == QImage::Format_A2RGB30_Premultiplied); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const int src_pad = (src->bytes_per_line >> 2) - src->width; + const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; + const quint32 *src_data = (quint32 *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + const quint32 *end = src_data + src->width; + while (src_data < end) { + *dest_data = qConvertArgb32ToA2rgb30<PixelOrder>(*src_data); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template<QtPixelOrder PixelOrder> +static void convert_A2RGB30_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_A2BGR30_Premultiplied || src->format == QImage::Format_A2RGB30_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const int src_pad = (src->bytes_per_line >> 2) - src->width; + const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; + const quint32 *src_data = (quint32 *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + const quint32 *end = src_data + src->width; + while (src_data < end) { + *dest_data = qConvertA2rgb30ToArgb32<PixelOrder>(*src_data); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +static inline uint qUnpremultiplyRgb30(uint rgb30) +{ + const uint a = rgb30 >> 30; + switch (a) { + case 0: + return 0; + case 1: { + uint rgb = rgb30 & 0x3fffffff; + rgb *= 3; + return (a << 30) | rgb; + } + case 2: { + uint rgb = rgb30 & 0x3fffffff; + rgb += rgb >> 1; + return (a << 30) | rgb; + } + case 3: + return rgb30; + } + Q_UNREACHABLE(); + return 0; +} + +static void convert_A2RGB30_PM_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_A2RGB30_Premultiplied || src->format == QImage::Format_A2BGR30_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_RGB30 || dest->format == QImage::Format_BGR30); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const int src_pad = (src->bytes_per_line >> 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 = 0xc0000000 | qUnpremultiplyRgb30(*src_data); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +static bool convert_A2RGB30_PM_to_RGB30_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_A2RGB30_Premultiplied || data->format == QImage::Format_A2BGR30_Premultiplied); + + const int pad = (data->bytes_per_line >> 2) - data->width; + uint *rgb_data = (uint *) data->data; + + for (int i = 0; i < data->height; ++i) { + const uint *end = rgb_data + data->width; + while (rgb_data < end) { + *rgb_data = 0xc0000000 | qUnpremultiplyRgb30(*rgb_data); + ++rgb_data; + } + rgb_data += pad; + } + + if (data->format == QImage::Format_A2RGB30_Premultiplied) + data->format = QImage::Format_RGB30; + else + data->format = QImage::Format_BGR30; + return true; +} + +static void convert_BGR30_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_RGB30 || src->format == QImage::Format_BGR30 || + src->format == QImage::Format_A2RGB30_Premultiplied || src->format == QImage::Format_A2BGR30_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_RGB30 || dest->format == QImage::Format_BGR30 || + dest->format == QImage::Format_A2RGB30_Premultiplied || dest->format == QImage::Format_A2BGR30_Premultiplied); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const int src_pad = (src->bytes_per_line >> 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 = qRgbSwapRgb30(*src_data); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +static bool convert_BGR30_to_RGB30_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_RGB30 || data->format == QImage::Format_BGR30 || + data->format == QImage::Format_A2RGB30_Premultiplied || data->format == QImage::Format_A2BGR30_Premultiplied); + + const int pad = (data->bytes_per_line >> 2) - data->width; + uint *rgb_data = (uint *) data->data; + + for (int i = 0; i < data->height; ++i) { + const uint *end = rgb_data + data->width; + while (rgb_data < end) { + *rgb_data = qRgbSwapRgb30(*rgb_data); + ++rgb_data; + } + rgb_data += pad; + } + + switch (data->format) { + case QImage::Format_BGR30: + data->format = QImage::Format_RGB30; + break; + case QImage::Format_A2BGR30_Premultiplied: + data->format = QImage::Format_A2RGB30_Premultiplied; + break; + case QImage::Format_RGB30: + data->format = QImage::Format_BGR30; + break; + case QImage::Format_A2RGB30_Premultiplied: + data->format = QImage::Format_A2BGR30_Premultiplied; + break; + default: + Q_UNREACHABLE(); + data->format = QImage::Format_Invalid; + return false; + } + return true; +} + static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags) { Q_ASSERT(data->format == QImage::Format_Indexed8); @@ -1557,7 +1872,7 @@ static void convert_Mono_to_Indexed8(QImageData *dest, const QImageData *src, Qt 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, @@ -1578,7 +1893,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_Mono { @@ -1600,7 +1915,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_MonoLSB { @@ -1622,7 +1937,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_Indexed8 { @@ -1644,7 +1959,11 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, convert_RGB_to_RGBA, convert_RGB_to_RGBA, - convert_RGB_to_RGBA + convert_RGB_to_RGBA, + convert_RGB_to_RGB30<PixelOrderBGR>, + convert_RGB_to_RGB30<PixelOrderBGR>, + convert_RGB_to_RGB30<PixelOrderRGB>, + convert_RGB_to_RGB30<PixelOrderRGB>, }, // Format_RGB32 { @@ -1667,6 +1986,10 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_ARGB_to_RGBx, convert_ARGB_to_RGBA, convert_ARGB_to_RGBA_PM, + convert_RGB_to_RGB30<PixelOrderBGR>, + 0, + convert_RGB_to_RGB30<PixelOrderRGB>, + 0, }, // Format_ARGB32 { @@ -1689,6 +2012,10 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_ARGB_PM_to_RGBx, convert_ARGB_PM_to_RGBA, convert_ARGB_to_RGBA, + convert_ARGB_PM_to_RGB30<PixelOrderBGR>, + convert_ARGB_to_A2RGB30<PixelOrderBGR>, + convert_ARGB_PM_to_RGB30<PixelOrderRGB>, + convert_ARGB_to_A2RGB30<PixelOrderRGB>, }, // Format_ARGB32_Premultiplied { @@ -1710,7 +2037,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_RGB16 { @@ -1732,7 +2059,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_ARGB8565_Premultiplied { @@ -1754,7 +2081,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_RGB666 { @@ -1776,7 +2103,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_ARGB6666_Premultiplied { @@ -1798,7 +2125,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_RGB555 { @@ -1820,7 +2147,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_ARGB8555_Premultiplied { @@ -1842,7 +2169,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_RGB888 { @@ -1864,7 +2191,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_RGB444 { @@ -1885,7 +2212,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_ARGB4444_Premultiplied { 0, @@ -1907,6 +2234,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, mask_alpha_converter_RGBx, mask_alpha_converter_RGBx, + 0, 0, 0, 0 }, // Format_RGBX8888 { 0, @@ -1933,6 +2261,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0 #endif + 0, 0, 0, 0 }, // Format_RGBA8888 { @@ -1961,19 +2290,121 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0 #endif - } // Format_RGBA8888_Premultiplied + 0, 0, 0, 0 + }, // Format_RGBA8888_Premultiplied + + { + 0, + 0, + 0, + 0, + convert_RGB30_to_RGB<PixelOrderBGR>, + convert_RGB30_to_RGB<PixelOrderBGR>, + convert_RGB30_to_RGB<PixelOrderBGR>, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_passthrough, + convert_BGR30_to_RGB30, + convert_BGR30_to_RGB30 + }, // Format_BGR30 + { + 0, + 0, + 0, + 0, + convert_A2RGB30_PM_to_RGB<PixelOrderBGR>, + 0, + convert_A2RGB30_to_ARGB<PixelOrderBGR>, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_A2RGB30_PM_to_RGB30, + 0, + 0, + convert_BGR30_to_RGB30 + }, // Format_BGR30A2_Premultiplied + { + 0, + 0, + 0, + 0, + convert_RGB30_to_RGB<PixelOrderRGB>, + convert_RGB30_to_RGB<PixelOrderRGB>, + convert_RGB30_to_RGB<PixelOrderRGB>, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_BGR30_to_RGB30, + convert_BGR30_to_RGB30, + 0, + 0, + convert_passthrough, + }, // Format_RGB30 + { + 0, + 0, + 0, + 0, + convert_A2RGB30_PM_to_RGB<PixelOrderRGB>, + 0, + convert_A2RGB30_to_ARGB<PixelOrderRGB>, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_BGR30_to_RGB30, + convert_A2RGB30_PM_to_RGB30, + 0, + }, // Format_RGB30A2_Premultiplied }; InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] = { { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 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 }, // Format_MonoLSB { 0, @@ -1994,7 +2425,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, + 0, 0, 0, 0, 0 }, // Format_Indexed8 { 0, @@ -2015,7 +2446,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, + 0, 0, 0, 0, 0 }, // Format_RGB32 { 0, @@ -2040,7 +2471,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, convert_ARGB_to_RGBA_inplace, - 0, + 0, 0, 0, 0, 0 }, // Format_ARGB32 { 0, @@ -2061,34 +2492,35 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - convert_ARGB_to_RGBA_inplace + convert_ARGB_to_RGBA_inplace, + 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // Format_ARGB4444_Premultiplied { 0, @@ -2108,8 +2540,9 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, - 0, + convert_passthrough_inplace<QImage::Format_RGBA8888>, + convert_passthrough_inplace<QImage::Format_RGBA8888_Premultiplied>, + 0, 0, 0, 0 }, // Format_RGBX8888 { 0, @@ -2131,6 +2564,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, + 0, 0, 0, 0 }, // Format_RGBA8888 { 0, @@ -2152,7 +2586,108 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - } // Format_RGBA8888_Premultiplied + 0, 0, 0, 0 + }, // Format_RGBA8888_Premultiplied + { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_passthrough_inplace<QImage::Format_A2BGR30_Premultiplied>, + convert_BGR30_to_RGB30_inplace, + convert_BGR30_to_RGB30_inplace + }, // Format_BGR30 + { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_A2RGB30_PM_to_RGB30_inplace, + 0, + 0, + convert_BGR30_to_RGB30_inplace + }, // Format_BGR30A2_Premultiplied + { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_BGR30_to_RGB30_inplace, + convert_BGR30_to_RGB30_inplace, + 0, + convert_passthrough_inplace<QImage::Format_A2RGB30_Premultiplied> + }, // Format_RGB30 + { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_BGR30_to_RGB30_inplace, + convert_A2RGB30_PM_to_RGB30_inplace, + 0 + }, // Format_RGB30A2_Premultiplied }; void qInitImageConversions() diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index 81730b92f2..a22e207812 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -130,7 +130,7 @@ inline int qt_depthForFormat(QImage::Format format) switch(format) { case QImage::Format_Invalid: case QImage::NImageFormats: - Q_ASSERT(false); + Q_UNREACHABLE(); case QImage::Format_Mono: case QImage::Format_MonoLSB: depth = 1; @@ -144,6 +144,10 @@ inline int qt_depthForFormat(QImage::Format format) case QImage::Format_RGBX8888: case QImage::Format_RGBA8888: case QImage::Format_RGBA8888_Premultiplied: + case QImage::Format_BGR30: + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_RGB30: + case QImage::Format_A2RGB30_Premultiplied: depth = 32; break; case QImage::Format_RGB555: diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index c6d8d19bb1..f4222d2360 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1511,7 +1511,8 @@ QBitmap QPixmap::mask() const return QBitmap(); const QImage img = toImage(); - const QImage image = (img.depth() < 32 ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied) : img); + bool shouldConvert = (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_ARGB32_Premultiplied); + const QImage image = (shouldConvert ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied) : img); const int w = image.width(); const int h = image.height(); diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp index 39f63a620c..64eaf7f19e 100644 --- a/src/gui/image/qppmhandler.cpp +++ b/src/gui/image/qppmhandler.cpp @@ -275,6 +275,8 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy case QImage::Format_RGB888: case QImage::Format_RGB444: case QImage::Format_RGBX8888: + case QImage::Format_BGR30: + case QImage::Format_RGB30: image = image.convertToFormat(QImage::Format_RGB32); break; case QImage::Format_ARGB8565_Premultiplied: @@ -283,6 +285,8 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy case QImage::Format_ARGB4444_Premultiplied: case QImage::Format_RGBA8888: case QImage::Format_RGBA8888_Premultiplied: + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_A2RGB30_Premultiplied: image = image.convertToFormat(QImage::Format_ARGB32); break; default: diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index f22c37aecc..438eb6f34f 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -403,7 +403,168 @@ void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl, } } +template<QtPixelOrder PixelOrder> +static void qt_blend_argb32pm_on_a2rgb30pm(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha) +{ +#ifdef QT_DEBUG_DRAW + fprintf(stdout, "qt_blend_argb32pm_on_a2rgb30pm: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n", + destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha); + fflush(stdout); +#endif + + const uint *src = (const uint *) srcPixels; + uint *dst = (uint *) destPixels; + if (const_alpha == 256) { + for (int y=0; y<h; ++y) { + for (int x=0; x<w; ++x) { + uint s = src[x]; + dst[x] = qConvertArgb32ToA2rgb30<PixelOrder>(s) + BYTE_MUL_RGB30(dst[x], 255 - qAlpha(s)); + } + dst = (quint32 *)(((uchar *) dst) + dbpl); + src = (const quint32 *)(((const uchar *) src) + sbpl); + } + } else if (const_alpha != 0) { + const_alpha = (const_alpha * 255) >> 8; + for (int y=0; y<h; ++y) { + for (int x=0; x<w; ++x) { + uint s = BYTE_MUL(src[x], const_alpha); + dst[x] = qConvertArgb32ToA2rgb30<PixelOrder>(s) + BYTE_MUL_RGB30(dst[x], 255 - qAlpha(s)); + } + dst = (quint32 *)(((uchar *) dst) + dbpl); + src = (const quint32 *)(((const uchar *) src) + sbpl); + } + } +} + +template<QtPixelOrder PixelOrder> +void qt_blend_rgb32_on_rgb30(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha) +{ +#ifdef QT_DEBUG_DRAW + fprintf(stdout, "qt_blend_rgb32_on_rgb30: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n", + destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha); + fflush(stdout); +#endif + + if (const_alpha != 256) { + qt_blend_argb32pm_on_a2rgb30pm<PixelOrder>(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha); + return; + } + + const uint *src = (const uint *) srcPixels; + uint *dst = (uint *) destPixels; + for (int y = 0; y < h; ++y) { + for (int x = 0; x < w; ++x) { + dst[x] = qConvertRgb32ToRgb30<PixelOrder>(src[x]); + } + dst = (quint32 *)(((uchar *) dst) + dbpl); + src = (const quint32 *)(((const uchar *) src) + sbpl); + } +} + +static void qt_blend_a2rgb30pm_on_a2rgb30pm(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha) +{ +#ifdef QT_DEBUG_DRAW + fprintf(stdout, "qt_blend_a2rgb30pm_on_a2rgb30pm: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n", + destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha); + fflush(stdout); +#endif + + const uint *src = (const uint *) srcPixels; + uint *dst = (uint *) destPixels; + if (const_alpha == 256) { + for (int y=0; y<h; ++y) { + for (int x=0; x<w; ++x) { + uint s = src[x]; + dst[x] = s + BYTE_MUL_RGB30(dst[x], 255 - qAlphaRgb30(s)); + } + dst = (quint32 *)(((uchar *) dst) + dbpl); + src = (const quint32 *)(((const uchar *) src) + sbpl); + } + } else if (const_alpha != 0) { + const uint const_alpha255 = (const_alpha * 255) >> 8; + for (int y=0; y<h; ++y) { + for (int x=0; x<w; ++x) { + uint a = (qAlphaRgb30(src[x]) * const_alpha) >> 8; + uint s = BYTE_MUL_RGB30(src[x], const_alpha255); + dst[x] = s + BYTE_MUL_RGB30(dst[x], 255 - a); + } + dst = (quint32 *)(((uchar *) dst) + dbpl); + src = (const quint32 *)(((const uchar *) src) + sbpl); + } + } +} + + +void qt_blend_rgb30_on_rgb30(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha) +{ +#ifdef QT_DEBUG_DRAW + fprintf(stdout, "qt_blend_rgb30_on_rgb30: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n", + destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha); + fflush(stdout); +#endif + + if (const_alpha != 256) { + qt_blend_a2rgb30pm_on_a2rgb30pm(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha); + return; + } + + const uint *src = (const uint *) srcPixels; + uint *dst = (uint *) destPixels; + int len = w * 4; + for (int y=0; y<h; ++y) { + memcpy(dst, src, len); + dst = (quint32 *)(((uchar *) dst) + dbpl); + src = (const quint32 *)(((const uchar *) src) + sbpl); + } +} +static void qt_blend_a2bgr30pm_on_a2rgb30pm(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha) +{ +#ifdef QT_DEBUG_DRAW + fprintf(stdout, "qt_blend_a2bgr30pm_on_a2rgb32pm: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n", + destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha); + fflush(stdout); +#endif + + const uint *src = (const uint *) srcPixels; + uint *dst = (uint *) destPixels; + if (const_alpha == 256) { + for (int y=0; y<h; ++y) { + for (int x=0; x<w; ++x) { + uint s = qRgbSwapRgb30(src[x]); + dst[x] = s + BYTE_MUL_RGB30(dst[x], 255 - qAlphaRgb30(s)); + } + dst = (quint32 *)(((uchar *) dst) + dbpl); + src = (const quint32 *)(((const uchar *) src) + sbpl); + } + } else if (const_alpha != 0) { + const uint const_alpha255 = (const_alpha * 255) >> 8; + for (int y=0; y<h; ++y) { + for (int x=0; x<w; ++x) { + uint a = (qAlphaRgb30(src[x]) * const_alpha) >> 8; + uint s = BYTE_MUL_RGB30(src[x], const_alpha255); + dst[x] = qRgbSwapRgb30(s) + BYTE_MUL_RGB30(dst[x], 255 - a); + } + dst = (quint32 *)(((uchar *) dst) + dbpl); + src = (const quint32 *)(((const uchar *) src) + sbpl); + } + } +} struct Blend_RGB32_on_RGB32_NoAlpha { inline void write(quint32 *dst, quint32 src) { *dst = src; } @@ -607,7 +768,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGRs30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_Mono 0, // Format_Invalid, @@ -628,7 +793,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_MonoLSB 0, // Format_Invalid, @@ -649,7 +818,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_Indexed8 0, // Format_Invalid, @@ -670,7 +843,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB32 0, // Format_Invalid, @@ -691,7 +868,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB32 0, // Format_Invalid, @@ -712,7 +893,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB32_Premultiplied 0, // Format_Invalid, @@ -733,7 +918,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB16 0, // Format_Invalid, @@ -754,7 +943,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB8565_Premultiplied 0, // Format_Invalid, @@ -775,7 +968,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB666 0, // Format_Invalid, @@ -796,7 +993,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB6666_Premultiplied 0, // Format_Invalid, @@ -817,7 +1018,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB555 0, // Format_Invalid, @@ -838,7 +1043,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB8555_Premultiplied 0, // Format_Invalid, @@ -859,7 +1068,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB888 0, // Format_Invalid, @@ -880,7 +1093,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB444 0, // Format_Invalid, @@ -901,7 +1118,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB4444_Premultiplied 0, // Format_Invalid, @@ -922,7 +1143,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGBX8888 0, // Format_Invalid, @@ -948,8 +1173,12 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = #else 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, #endif + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGBA8888 0, // Format_Invalid, @@ -970,7 +1199,11 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGBA8888_Premultiplied 0, // Format_Invalid, @@ -996,9 +1229,113 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = #else 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, #endif - } + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, + }, + { // Format_BGR30 + 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, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, + }, + { // Format_A2BGR30_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, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, + }, + { // Format_RGB30 + 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, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, + }, + { // Format_A2RGB30_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, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, + }, }; @@ -1022,7 +1359,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_Mono 0, // Format_Invalid, @@ -1043,7 +1384,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_MonoLSB 0, // Format_Invalid, @@ -1064,7 +1409,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_Indexed8 0, // Format_Invalid, @@ -1085,7 +1434,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB32 0, // Format_Invalid, @@ -1106,7 +1459,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB32 0, // Format_Invalid, @@ -1127,7 +1484,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB32_Premultiplied 0, // Format_Invalid, @@ -1148,7 +1509,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB16 0, // Format_Invalid, @@ -1169,7 +1534,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB8565_Premultiplied 0, // Format_Invalid, @@ -1190,7 +1559,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB666 0, // Format_Invalid, @@ -1211,7 +1584,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB6666_Premultiplied 0, // Format_Invalid, @@ -1232,7 +1609,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB555 0, // Format_Invalid, @@ -1253,7 +1634,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB8555_Premultiplied 0, // Format_Invalid, @@ -1274,7 +1659,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB888 0, // Format_Invalid, @@ -1295,7 +1684,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB444 0, // Format_Invalid, @@ -1316,7 +1709,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB4444_Premultiplied 0, // Format_Invalid, @@ -1337,7 +1734,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGBX8888 0, // Format_Invalid, @@ -1363,8 +1764,12 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = #else 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, #endif + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGBA8888 0, // Format_Invalid, @@ -1385,7 +1790,11 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGBA8888_Premultiplied 0, // Format_Invalid, @@ -1411,9 +1820,113 @@ SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = #else 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, #endif - } + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0, // Format_A2RGB30_Premultiplied, + }, + { // Format_BGR30 + 0, // Format_Invalid, + 0, // Format_Mono, + 0, // Format_MonoLSB, + 0, // Format_Indexed8, + qt_blend_rgb32_on_rgb30<PixelOrderBGR>, // Format_RGB32, + 0, // Format_ARGB32, + qt_blend_argb32pm_on_a2rgb30pm<PixelOrderBGR>, // 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, + qt_blend_rgb30_on_rgb30, // Format_RGB30, + qt_blend_a2rgb30pm_on_a2rgb30pm, // Format_A2RGB30_Premultiplied, + qt_blend_a2bgr30pm_on_a2rgb30pm, // Format_RGB30, + qt_blend_a2bgr30pm_on_a2rgb30pm, // Format_A2RGB30_Premultiplied, + }, + { // Format_A2BGR30_Premultiplied + 0, // Format_Invalid, + 0, // Format_Mono, + 0, // Format_MonoLSB, + 0, // Format_Indexed8, + qt_blend_rgb32_on_rgb30<PixelOrderBGR>, // Format_RGB32, + 0, // Format_ARGB32, + qt_blend_argb32pm_on_a2rgb30pm<PixelOrderBGR>, // 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, + qt_blend_rgb30_on_rgb30, // Format_BGR30, + qt_blend_a2rgb30pm_on_a2rgb30pm, // Format_A2BGR30_Premultiplied, + qt_blend_a2bgr30pm_on_a2rgb30pm, // Format_RGB30, + qt_blend_a2bgr30pm_on_a2rgb30pm, // Format_A2RGB30_Premultiplied, + }, + { // Format_RGB30 + 0, // Format_Invalid, + 0, // Format_Mono, + 0, // Format_MonoLSB, + 0, // Format_Indexed8, + qt_blend_rgb32_on_rgb30<PixelOrderRGB>, // Format_RGB32, + 0, // Format_ARGB32, + qt_blend_argb32pm_on_a2rgb30pm<PixelOrderRGB>, // 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, + qt_blend_a2bgr30pm_on_a2rgb30pm, // Format_BGR30, + qt_blend_a2bgr30pm_on_a2rgb30pm, // Format_A2BGR30_Premultiplied, + qt_blend_rgb30_on_rgb30, // Format_RGB30, + qt_blend_a2rgb30pm_on_a2rgb30pm, // Format_A2RGB30_Premultiplied, + }, + { // Format_A2RGB30_Premultiplied + 0, // Format_Invalid, + 0, // Format_Mono, + 0, // Format_MonoLSB, + 0, // Format_Indexed8, + qt_blend_rgb32_on_rgb30<PixelOrderRGB>, // Format_RGB32, + 0, // Format_ARGB32, + qt_blend_argb32pm_on_a2rgb30pm<PixelOrderRGB>, // 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, + qt_blend_a2bgr30pm_on_a2rgb30pm, // Format_BGR30, + qt_blend_a2bgr30pm_on_a2rgb30pm, // Format_A2BGR30_Premultiplied, + qt_blend_rgb30_on_rgb30, // Format_RGB30, + qt_blend_a2rgb30pm_on_a2rgb30pm // Format_A2RGB30_Premultiplied, + }, }; SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFormats] = { @@ -1436,7 +1949,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_Mono 0, // Format_Invalid, @@ -1457,7 +1974,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_MonoLSB 0, // Format_Invalid, @@ -1478,7 +1999,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_Indexed8 0, // Format_Invalid, @@ -1499,7 +2024,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB32 0, // Format_Invalid, @@ -1520,7 +2049,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB32 0, // Format_Invalid, @@ -1541,7 +2074,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB32_Premultiplied 0, // Format_Invalid, @@ -1562,7 +2099,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB16 0, // Format_Invalid, @@ -1583,7 +2124,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB8565_Premultiplied 0, // Format_Invalid, @@ -1604,7 +2149,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB666 0, // Format_Invalid, @@ -1625,7 +2174,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB6666_Premultiplied 0, // Format_Invalid, @@ -1646,7 +2199,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB555 0, // Format_Invalid, @@ -1667,7 +2224,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB8555_Premultiplied 0, // Format_Invalid, @@ -1688,7 +2249,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB888 0, // Format_Invalid, @@ -1709,7 +2274,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGB444 0, // Format_Invalid, @@ -1730,7 +2299,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_ARGB4444_Premultiplied 0, // Format_Invalid, @@ -1751,7 +2324,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGBX8888 0, // Format_Invalid, @@ -1777,8 +2354,12 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo #else 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, #endif + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGBA8888 0, // Format_Invalid, @@ -1799,7 +2380,11 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo 0, // Format_ARGB4444_Premultiplied, 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, }, { // Format_RGBA8888_Premultiplied 0, // Format_Invalid, @@ -1825,9 +2410,113 @@ SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFo #else 0, // Format_RGBX8888, 0, // Format_RGBA8888, - 0 // Format_RGBA8888_Premultiplied, + 0, // Format_RGBA8888_Premultiplied, #endif - } + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, + }, + { // Format_BGR30 + 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, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, + }, + { // Format_A2BGR30_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, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, + }, + { // Format_RGB30 + 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, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, + }, + { // Format_A2RGB30_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, + 0, // Format_RGBX8888, + 0, // Format_RGBA8888, + 0, // Format_RGBA8888_Premultiplied, + 0, // Format_BGR30, + 0, // Format_A2BGR30_Premultiplied, + 0, // Format_RGB30, + 0 // Format_A2RGB30_Premultiplied, + }, }; QT_END_NAMESPACE diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 44b38dcf1c..ffb952bce4 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -575,6 +575,42 @@ static const uint *QT_FASTCALL convertRGBXFromARGB32PM(uint *buffer, const uint return buffer; } +template<QtPixelOrder PixelOrder> +static const uint *QT_FASTCALL convertA2RGB30PMToARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = qConvertA2rgb30ToArgb32<PixelOrder>(src[i]); + return buffer; +} + +template<QtPixelOrder PixelOrder> +static const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = qConvertArgb32ToA2rgb30<PixelOrder>(src[i]); + return buffer; +} + +template<QtPixelOrder PixelOrder> +static const uint *QT_FASTCALL convertRGB30FromRGB32(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = qConvertRgb32ToRgb30<PixelOrder>(src[i]); + return buffer; +} + +template<QtPixelOrder PixelOrder> +static const uint *QT_FASTCALL convertRGB30FromARGB32PM(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = qConvertRgb32ToRgb30<PixelOrder>(qUnpremultiply(src[i])); + return buffer; +} + template <QPixelLayout::BPP bpp> static uint QT_FASTCALL fetchPixel(const uchar *src, int index); @@ -722,8 +758,12 @@ QPixelLayout qPixelLayouts[QImage::NImageFormats] = { #else { 8, 0, 8, 8, 8, 16, 0, 24, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBX8888 { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, 0 }, // Format_RGBA8888 (ABGR32) - { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, 0 } // Format_RGBA8888_Premultiplied + { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, 0 }, // Format_RGBA8888_Premultiplied #endif + { 10, 20, 10, 10, 10, 0, 0, 30, false, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderBGR>, convertRGB30FromARGB32PM<PixelOrderBGR>, convertRGB30FromRGB32<PixelOrderBGR> }, // Format_BGR30 + { 10, 20, 10, 10, 10, 0, 2, 30, true, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderBGR>, convertA2RGB30PMFromARGB32PM<PixelOrderBGR>, 0 }, // Format_A2BGR30_Premultiplied + { 10, 0, 10, 10, 10, 20, 0, 30, false, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderRGB>, convertRGB30FromARGB32PM<PixelOrderRGB>, convertRGB30FromRGB32<PixelOrderRGB> }, // Format_RGB30 + { 10, 0, 10, 10, 10, 20, 2, 30, true, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderRGB>, convertA2RGB30PMFromARGB32PM<PixelOrderRGB>, 0 }, // Format_A2RGB30_Premultiplied }; FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount] = { @@ -831,6 +871,10 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] = destFetch, // Format_RGBX8888 destFetch, // Format_RGBA8888 destFetch, // Format_RGBA8888_Premultiplied + destFetch, // Format_BGR30 + destFetch, // Format_A2BGR30_Premultiplied + destFetch, // Format_RGB30 + destFetch, // Format_A2RGB30_Premultiplied }; /* @@ -970,7 +1014,11 @@ static DestStoreProc destStoreProc[QImage::NImageFormats] = destStore, // Format_ARGB4444_Premultiplied destStore, // Format_RGBX8888 destStore, // Format_RGBA8888 - destStore // Format_RGBA8888_Premultiplied + destStore, // Format_RGBA8888_Premultiplied + destStore, // Format_BGR30 + destStore, // Format_A2BGR30_Premultiplied + destStore, // Format_RGB30 + destStore, // Format_A2RGB30_Premultiplied }; /* @@ -2221,7 +2269,11 @@ static SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { fetchUntransformed, // ARGB4444_Premultiplied fetchUntransformed, // RGBX8888 fetchUntransformed, // RGBA8888 - fetchUntransformed // RGBA8888_Premultiplied + fetchUntransformed, // RGBA8888_Premultiplied + fetchUntransformed, // Format_BGR30 + fetchUntransformed, // Format_A2BGR30_Premultiplied + fetchUntransformed, // Format_RGB30 + fetchUntransformed, // Format_A2RGB30_Premultiplied }, // Tiled { @@ -2243,7 +2295,11 @@ static SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { fetchUntransformed, // ARGB4444_Premultiplied fetchUntransformed, // RGBX8888 fetchUntransformed, // RGBA8888 - fetchUntransformed // RGBA8888_Premultiplied + fetchUntransformed, // RGBA8888_Premultiplied + fetchUntransformed, // BGR30 + fetchUntransformed, // A2BGR30_Premultiplied + fetchUntransformed, // RGB30 + fetchUntransformed // A2RGB30_Premultiplied }, // Transformed { @@ -2266,6 +2322,10 @@ static SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { fetchTransformed<BlendTransformed>, // RGBX8888 fetchTransformed<BlendTransformed>, // RGBA8888 fetchTransformed<BlendTransformed>, // RGBA8888_Premultiplied + fetchTransformed<BlendTransformed>, // BGR30 + fetchTransformed<BlendTransformed>, // A2BGR30_Premultiplied + fetchTransformed<BlendTransformed>, // RGB30 + fetchTransformed<BlendTransformed>, // A2RGB30_Premultiplied }, { 0, // TransformedTiled @@ -2287,6 +2347,10 @@ static SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { fetchTransformed<BlendTransformedTiled>, // RGBX8888 fetchTransformed<BlendTransformedTiled>, // RGBA8888 fetchTransformed<BlendTransformedTiled>, // RGBA8888_Premultiplied + fetchTransformed<BlendTransformedTiled>, // BGR30 + fetchTransformed<BlendTransformedTiled>, // A2BGR30_Premultiplied + fetchTransformed<BlendTransformedTiled>, // RGB30 + fetchTransformed<BlendTransformedTiled>, // A2RGB30_Premultiplied }, { 0, // Bilinear @@ -2307,7 +2371,11 @@ static SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { fetchTransformedBilinear<BlendTransformedBilinear>, // ARGB4444_Premultiplied fetchTransformedBilinear<BlendTransformedBilinear>, // RGBX8888 fetchTransformedBilinear<BlendTransformedBilinear>, // RGBA8888 - fetchTransformedBilinear<BlendTransformedBilinear> // RGBA8888_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinear>, // RGBA8888_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinear>, // BGR30 + fetchTransformedBilinear<BlendTransformedBilinear>, // A2BGR30_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinear>, // RGB30 + fetchTransformedBilinear<BlendTransformedBilinear>, // A2RGB30_Premultiplied }, { 0, // BilinearTiled @@ -2328,7 +2396,11 @@ static SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { fetchTransformedBilinear<BlendTransformedBilinearTiled>, // ARGB4444_Premultiplied fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGBX8888 fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGBA8888 - fetchTransformedBilinear<BlendTransformedBilinearTiled> // RGBA8888_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGBA8888_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinearTiled>, // BGR30 + fetchTransformedBilinear<BlendTransformedBilinearTiled>, // A2BGR30_Premultiplied + fetchTransformedBilinear<BlendTransformedBilinearTiled>, // RGB30 + fetchTransformedBilinear<BlendTransformedBilinearTiled> // A2RGB30_Premultiplied }, }; @@ -5749,6 +5821,10 @@ 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, + blend_untransformed_generic, }, // Tiled { @@ -5771,6 +5847,10 @@ 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, + blend_tiled_generic, }, // Transformed { @@ -5793,6 +5873,10 @@ 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, }, // TransformedTiled { @@ -5814,6 +5898,10 @@ 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, blend_src_generic }, // Bilinear @@ -5837,6 +5925,10 @@ 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, }, // BilinearTiled { @@ -5859,6 +5951,10 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats blend_src_generic, // RGBX8888 blend_src_generic, // RGBA8888 blend_src_generic, // RGBA8888_Premultiplied + blend_src_generic, // BGR30 + blend_src_generic, // A2BGR30_Premultiplied + blend_src_generic, // RGB30 + blend_src_generic, // A2RGB30_Premultiplied } }; @@ -6379,7 +6475,6 @@ static void qt_rectfill_nonpremul_rgba(QRasterBuffer *rasterBuffer, ARGB2RGBA(qUnpremultiply(color)), x, y, width, height, rasterBuffer->bytesPerLine()); } - // Map table for destination image format. Contains function pointers // for blends of various types unto the destination @@ -6527,7 +6622,43 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = #endif 0, qt_rectfill_rgba - } + }, + // Format_BGR30 + { + blend_color_generic, + blend_src_generic, + 0, + 0, + 0, + 0 + }, + // Format_A2BGR30_Premultiplied + { + blend_color_generic, + blend_src_generic, + 0, + 0, + 0, + 0 + }, + // Format_RGB30 + { + blend_color_generic, + blend_src_generic, + 0, + 0, + 0, + 0 + }, + // Format_A2RGB30_Premultiplied + { + blend_color_generic, + blend_src_generic, + 0, + 0, + 0, + 0 + }, }; #if defined(Q_CC_MSVC) && !defined(_MIPS_) diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 1c05fc305a..d6b557af01 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -672,6 +672,36 @@ static Q_ALWAYS_INLINE uint BYTE_MUL_RGB16_32(uint x, uint a) { return t; } +#if defined(Q_CC_RVCT) +# pragma push +# pragma arm +#endif +static Q_ALWAYS_INLINE int qt_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; } +#if defined(Q_CC_RVCT) +# pragma pop +#endif + +static Q_ALWAYS_INLINE uint BYTE_MUL_RGB30(uint x, uint a) { + uint xa = x >> 30; + uint xr = (x >> 20) & 0x3ff; + uint xg = (x >> 10) & 0x3ff; + uint xb = x & 0x3ff; + xa = qt_div_255(xa * a); + xr = qt_div_255(xr * a); + xg = qt_div_255(xg * a); + xb = qt_div_255(xb * a); + return (xa << 30) | (xr << 20) | (xg << 10) | xb; +} + +static Q_ALWAYS_INLINE uint qAlphaRgb30(uint c) +{ + uint a = c >> 30; + a |= a << 2; + a |= a << 4; + return a; +} + + // FIXME: Remove when all Qt modules have stopped using PREMUL and INV_PREMUL #define PREMUL(x) qPremultiply(x) #define INV_PREMUL(p) qUnpremultiply(p) @@ -795,15 +825,6 @@ do { \ } \ } while (0) -#if defined(Q_CC_RVCT) -# pragma push -# pragma arm -#endif -static Q_ALWAYS_INLINE int qt_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; } -#if defined(Q_CC_RVCT) -# pragma pop -#endif - inline ushort qConvertRgb32To16(uint c) { return (((c) >> 3) & 0x001f) @@ -819,6 +840,84 @@ inline QRgb qConvertRgb16To32(uint c) | ((((c) << 8) & 0xf80000) | (((c) << 3) & 0x70000)); } +enum QtPixelOrder { + PixelOrderRGB, + PixelOrderBGR +}; + +template<enum QtPixelOrder> inline uint qConvertArgb32ToA2rgb30(QRgb); + +template<enum QtPixelOrder> inline uint qConvertRgb32ToRgb30(QRgb); + +template<enum QtPixelOrder> inline QRgb qConvertA2rgb30ToArgb32(uint c); + +template<> +inline uint qConvertArgb32ToA2rgb30<PixelOrderBGR>(QRgb c) +{ + return (c & 0xc0000000) + | (((c << 22) & 0x3fc00000) | ((c << 14) & 0x00300000)) + | (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00)) + | (((c >> 14) & 0x000003fc) | ((c >> 22) & 0x00000003)); +} + +template<> +inline uint qConvertArgb32ToA2rgb30<PixelOrderRGB>(QRgb c) +{ + return (c & 0xc0000000) + | (((c << 6) & 0x3fc00000) | ((c >> 2) & 0x00300000)) + | (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00)) + | (((c << 2) & 0x000003fc) | ((c >> 6) & 0x00000003)); +} + +template<> +inline uint qConvertRgb32ToRgb30<PixelOrderBGR>(QRgb c) +{ + return 0xc0000000 + | (((c << 22) & 0x3fc00000) | ((c << 14) & 0x00300000)) + | (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00)) + | (((c >> 14) & 0x000003fc) | ((c >> 22) & 0x00000003)); +} + +template<> +inline uint qConvertRgb32ToRgb30<PixelOrderRGB>(QRgb c) +{ + return 0xc0000000 + | (((c << 6) & 0x3fc00000) | ((c >> 2) & 0x00300000)) + | (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00)) + | (((c << 2) & 0x000003fc) | ((c >> 6) & 0x00000003)); +} + +template<> +inline QRgb qConvertA2rgb30ToArgb32<PixelOrderBGR>(uint c) +{ + uint a = c >> 30; + a |= a << 2; + a |= a << 4; + return (a << 24) + | ((c << 14) & 0x00ff0000) + | ((c >> 4) & 0x0000ff00) + | ((c >> 22) & 0x000000ff); +} + +template<> +inline QRgb qConvertA2rgb30ToArgb32<PixelOrderRGB>(uint c) +{ + uint a = c >> 30; + a |= a << 2; + a |= a << 4; + return (a << 24) + | ((c >> 6) & 0x00ff0000) + | ((c >> 4) & 0x0000ff00) + | ((c >> 2) & 0x000000ff); +} + +inline uint qRgbSwapRgb30(uint c) +{ + const uint ag = c & 0xc00ffc00; + const uint rb = c & 0x3ff003ff; + return ag | (rb << 20) | (rb >> 20); +} + inline int qRed565(quint16 rgb) { const int r = (rgb & 0xf800); return (r >> 8) | (r >> 13); diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp index 087231df43..e5eb7cf22d 100644 --- a/src/gui/painting/qmemrotate.cpp +++ b/src/gui/painting/qmemrotate.cpp @@ -532,7 +532,10 @@ MemRotateFunc qMemRotateFunctions[QImage::NImageFormats][3] = { 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_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_RGBA8888_Premultiplied, + { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_RGB30, + { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_A2RGB30, + { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 } // Format_A2RGB30_Premultiplied, }; QT_END_NAMESPACE diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index a004428fab..2e340219b9 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -423,6 +423,8 @@ void QRasterPaintEngine::init() case QImage::Format_ARGB32: case QImage::Format_RGBA8888_Premultiplied: case QImage::Format_RGBA8888: + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_A2RGB30_Premultiplied: gccaps |= PorterDuff; break; case QImage::Format_RGB32: @@ -432,6 +434,8 @@ void QRasterPaintEngine::init() case QImage::Format_RGB888: case QImage::Format_RGB16: case QImage::Format_RGBX8888: + case QImage::Format_BGR30: + case QImage::Format_RGB30: break; default: break; @@ -2243,6 +2247,8 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe case QImage::Format_ARGB8555_Premultiplied: case QImage::Format_ARGB4444_Premultiplied: case QImage::Format_RGBA8888_Premultiplied: + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_A2RGB30_Premultiplied: // Combine premultiplied color with the opacity set on the painter. d->solid_color_filler.solid.color = ((((color & 0x00ff00ff) * s->intOpacity) >> 8) & 0x00ff00ff) diff --git a/src/plugins/platforms/xcb/qxcbimage.cpp b/src/plugins/platforms/xcb/qxcbimage.cpp index 181d99e85b..bc800524ef 100644 --- a/src/plugins/platforms/xcb/qxcbimage.cpp +++ b/src/plugins/platforms/xcb/qxcbimage.cpp @@ -68,6 +68,14 @@ QImage::Format qt_xcb_imageFormatForVisual(QXcbConnection *connection, uint8_t d && visual->green_mask == 0xff00 && visual->blue_mask == 0xff) return QImage::Format_ARGB32_Premultiplied; + if (depth == 30 && format->bits_per_pixel == 32 && visual->red_mask == 0x3ff + && visual->green_mask == 0x0ffc00 && visual->blue_mask == 0x3ff00000) + return QImage::Format_BGR30; + + if (depth == 30 && format->bits_per_pixel == 32 && visual->blue_mask == 0x3ff + && visual->green_mask == 0x0ffc00 && visual->red_mask == 0x3ff00000) + return QImage::Format_RGB30; + if (depth == 24 && format->bits_per_pixel == 32 && visual->red_mask == 0xff0000 && visual->green_mask == 0xff00 && visual->blue_mask == 0xff) return QImage::Format_RGB32; @@ -147,6 +155,13 @@ QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap p[x] |= 0xff000000; p += bytes_per_line / 4; } + } else if (format == QImage::Format_BGR30 || format == QImage::Format_RGB30) { + QRgb *p = (QRgb *)image.bits(); + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) + p[x] |= 0xc0000000; + p += bytes_per_line / 4; + } } result = QPixmap::fromImage(image.copy()); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index dd3084e402..908e03cd7c 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -166,16 +166,36 @@ static inline bool isTransient(const QWindow *w) || w->type() == Qt::Popup; } -static inline QImage::Format imageFormatForDepth(int depth) +static inline QImage::Format imageFormatForVisual(int depth, quint32 red_mask, quint32 blue_mask) { switch (depth) { - case 32: return QImage::Format_ARGB32_Premultiplied; - case 24: return QImage::Format_RGB32; - case 16: return QImage::Format_RGB16; - default: - qWarning("Unsupported screen depth: %d", depth); - return QImage::Format_Invalid; + case 32: + if (blue_mask == 0xff) + return QImage::Format_ARGB32_Premultiplied; + if (red_mask == 0x3ff) + return QImage::Format_A2BGR30_Premultiplied; + if (blue_mask == 0x3ff) + return QImage::Format_A2RGB30_Premultiplied; + break; + case 30: + if (red_mask == 0x3ff) + return QImage::Format_BGR30; + if (blue_mask == 0x3ff) + return QImage::Format_RGB30; + break; + case 24: + if (blue_mask == 0xff) + return QImage::Format_RGB32; + break; + case 16: + if (blue_mask == 0x1f) + return QImage::Format_RGB16; + break; + default: + break; } + qWarning("Unsupported screen format: depth: %d, red_mask: %x, blue_mask: %x", depth, red_mask, blue_mask); + return QImage::Format_Invalid; } static inline bool positionIncludesFrame(QWindow *w) @@ -227,7 +247,9 @@ void QXcbWindow::create() if (type == Qt::Desktop) { m_window = m_screen->root(); m_depth = m_screen->screen()->root_depth; - m_imageFormat = imageFormatForDepth(m_depth); + m_visualId = m_screen->screen()->root_visual; + const xcb_visualtype_t *visual = m_screen->visualForId(m_visualId); + m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask); connection()->addWindowEventListener(m_window, this); return; } @@ -317,7 +339,7 @@ void QXcbWindow::create() } if (visualInfo) { m_depth = visualInfo->depth; - m_imageFormat = imageFormatForDepth(m_depth); + m_imageFormat = imageFormatForVisual(visualInfo->depth, visualInfo->red_mask, visualInfo->blue_mask); Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), xcb_parent_id, visualInfo->visual, AllocNone); XSetWindowAttributes a; @@ -367,7 +389,8 @@ void QXcbWindow::create() } } - m_imageFormat = imageFormatForDepth(m_depth); + const xcb_visualtype_t *visual = m_screen->visualForId(m_visualId); + m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask); Q_XCB_CALL(xcb_create_window(xcb_connection(), m_depth, diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 0a4456e22a..e2135ad6f0 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -766,6 +766,13 @@ void tst_QImage::convertToFormat_data() << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f7f7fu; QTest::newRow("semiblack rgba8888 -> argb pm") << int(QImage::Format_RGBA8888) << 0x7f000000u << int(QImage::Format_ARGB32_Premultiplied) << 0x7f000000u; + + QTest::newRow("red rgb30 -> argb32") << int(QImage::Format_RGB30) << 0xffff0000 + << int(QImage::Format_ARGB32) << 0xffff0000; + QTest::newRow("green rgb30 -> argb32") << int(QImage::Format_RGB30) << 0xff00ff00 + << int(QImage::Format_ARGB32) << 0xff00ff00; + QTest::newRow("blue rgb30 -> argb32") << int(QImage::Format_RGB30) << 0xff0000ff + << int(QImage::Format_ARGB32) << 0xff0000ff; } @@ -1218,6 +1225,18 @@ void tst_QImage::setPixel_data() QTest::newRow("RGBA8888 blue") << int(QImage::Format_RGBA8888) << 0xff0000ffu << 0xffff0000u; #endif + QTest::newRow("A2BGR30_Premultiplied red") << int(QImage::Format_A2BGR30_Premultiplied) + << 0xffff0000u << 0xc00003ffu; + QTest::newRow("A2BGR30_Premultiplied green") << int(QImage::Format_A2BGR30_Premultiplied) + << 0xff00ff00u << 0xc00ffc00u; + QTest::newRow("A2BGR30_Premultiplied blue") << int(QImage::Format_A2BGR30_Premultiplied) + << 0xff0000ffu << 0xfff00000u; + QTest::newRow("RGB30 red") << int(QImage::Format_RGB30) + << 0xffff0000u << 0xfff00000u; + QTest::newRow("RGB30 green") << int(QImage::Format_RGB30) + << 0xff00ff00u << 0xc00ffc00u; + QTest::newRow("RGB30 blue") << int(QImage::Format_RGB30) + << 0xff0000ffu << 0xc00003ffu; } void tst_QImage::setPixel() @@ -1244,6 +1263,8 @@ void tst_QImage::setPixel() case int(QImage::Format_RGBX8888): case int(QImage::Format_RGBA8888): case int(QImage::Format_RGBA8888_Premultiplied): + case int(QImage::Format_A2BGR30_Premultiplied): + case int(QImage::Format_RGB30): { for (int y = 0; y < h; ++y) { const quint32 *row = (const quint32*)(img.scanLine(y)); @@ -1963,6 +1984,8 @@ void tst_QImage::fillColor_data() "ARGB4444pm", "RGBx8888", "RGBA8888pm", + "BGR30", + "A2RGB30pm", 0 }; @@ -1982,6 +2005,8 @@ void tst_QImage::fillColor_data() QImage::Format_ARGB4444_Premultiplied, QImage::Format_RGBX8888, QImage::Format_RGBA8888_Premultiplied, + QImage::Format_BGR30, + QImage::Format_A2RGB30_Premultiplied, }; for (int i=0; names[i] != 0; ++i) { @@ -2000,6 +2025,7 @@ void tst_QImage::fillColor_data() QTest::newRow("ARGB32, transparent") << QImage::Format_ARGB32 << Qt::transparent << 0x00000000u; QTest::newRow("ARGB32pm, transparent") << QImage::Format_ARGB32_Premultiplied << Qt::transparent << 0x00000000u; QTest::newRow("RGBA8888pm, transparent") << QImage::Format_RGBA8888_Premultiplied << Qt::transparent << 0x00000000u; + QTest::newRow("A2RGB30pm, transparent") << QImage::Format_A2RGB30_Premultiplied << Qt::transparent << 0x00000000u; } void tst_QImage::fillColor() @@ -2116,6 +2142,8 @@ void tst_QImage::rgbSwapped_data() QTest::newRow("Format_RGB444") << QImage::Format_RGB444; QTest::newRow("Format_RGBX8888") << QImage::Format_RGBX8888; QTest::newRow("Format_RGBA8888_Premultiplied") << QImage::Format_RGBA8888_Premultiplied; + QTest::newRow("Format_A2BGR30_Premultiplied") << QImage::Format_A2BGR30_Premultiplied; + QTest::newRow("Format_RGB30") << QImage::Format_RGB30; } void tst_QImage::rgbSwapped() @@ -2184,6 +2212,8 @@ void tst_QImage::mirrored_data() 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; + QTest::newRow("Format_A2BGR30_Premultiplied, vertical") << QImage::Format_A2BGR30_Premultiplied << true << false << 16 << 16; + QTest::newRow("Format_RGB30, vertical") << QImage::Format_RGB30 << true << false << 16 << 16; QTest::newRow("Format_Indexed8, vertical") << QImage::Format_Indexed8 << true << false << 16 << 16; QTest::newRow("Format_Mono, vertical") << QImage::Format_Mono << true << false << 16 << 16; QTest::newRow("Format_MonoLSB, vertical") << QImage::Format_MonoLSB << true << false << 16 << 16; @@ -2283,6 +2313,7 @@ void tst_QImage::inplaceRgbSwapped_data() QTest::newRow("Format_ARGB32_Premultiplied") << QImage::Format_ARGB32_Premultiplied; QTest::newRow("Format_RGBA8888") << QImage::Format_RGBA8888; + QTest::newRow("Format_A2RGB30_Premultiplied") << QImage::Format_A2RGB30_Premultiplied; QTest::newRow("Format_RGB888") << QImage::Format_RGB888; QTest::newRow("Format_RGB16") << QImage::Format_RGB16; QTest::newRow("Format_Indexed8") << QImage::Format_Indexed8; diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 4604f840da..5af5b1a269 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -1136,6 +1136,8 @@ void tst_QPainter::fillRect2_data() QTest::newRow("argb32pm") << QImage::Format_ARGB32_Premultiplied; QTest::newRow("rgba8888") << QImage::Format_RGBA8888; QTest::newRow("rgba8888pm") << QImage::Format_RGBA8888_Premultiplied; + QTest::newRow("a2rgb30pm") << QImage::Format_A2RGB30_Premultiplied; + QTest::newRow("a2bgr30pm") << QImage::Format_A2BGR30_Premultiplied; } void tst_QPainter::fillRect2() @@ -1528,6 +1530,8 @@ 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_A2RGB30_Premultiplied") << QImage::Format_A2RGB30_Premultiplied; + QTest::newRow("Qimage::Format_RGB30") << QImage::Format_RGB30; } /* @@ -2344,6 +2348,26 @@ void tst_QPainter::setOpacity_data() QTest::newRow("RGB32 on RGBx8888") << QImage::Format_RGB32 << QImage::Format_RGBX8888; + + QTest::newRow("A2RGB30P on A2RGB30P") << QImage::Format_A2RGB30_Premultiplied + << QImage::Format_A2RGB30_Premultiplied; + + QTest::newRow("ARGB32P on A2RGB30P") << QImage::Format_ARGB32_Premultiplied + << QImage::Format_A2RGB30_Premultiplied; + + + QTest::newRow("RGB32 on A2BGR30P") << QImage::Format_ARGB32_Premultiplied + << QImage::Format_A2BGR30_Premultiplied; + + QTest::newRow("A2RGB30P on A2BGR30P") << QImage::Format_A2RGB30_Premultiplied + << QImage::Format_A2BGR30_Premultiplied; + + QTest::newRow("ARGB32P on BGR30") << QImage::Format_ARGB32_Premultiplied + << QImage::Format_BGR30; + + QTest::newRow("ARGB32P on RGB30") << QImage::Format_A2RGB30_Premultiplied + << QImage::Format_RGB30; + } void tst_QPainter::setOpacity() @@ -2432,7 +2456,9 @@ void tst_QPainter::drawhelper_blend_untransformed() dest.bytesPerLine(), dest.format()); if (dest.format() == QImage::Format_ARGB8565_Premultiplied || - dest.format() == QImage::Format_ARGB8555_Premultiplied) { + dest.format() == QImage::Format_ARGB8555_Premultiplied || + dest.format() == QImage::Format_A2BGR30_Premultiplied || + dest.format() == QImage::Format_A2RGB30_Premultiplied ) { // Test skipped due to rounding errors... continue; } |