diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-07-05 13:04:26 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-10-02 08:06:21 +0000 |
commit | 6f16b7a8f33c9641850809562b627f9da12fa9ad (patch) | |
tree | 807dfa54222ce4b72e639f01285b494121211a93 /src/gui/image/qimage.cpp | |
parent | b6f69206548f7bd15c72ba35d7c2e3b66b1abb7a (diff) |
Handle endian mismatch between X11 client and server
If the server and client has different endian we need to swizzle the
image pixels, we can do that by swizzling the masks and try to match
the new configuration. This is a rather rare setup so we don't try
to match every combination.
This patch fixes the colors when running Qt in a bigendian QEMU chroot.
Change-Id: Ie83f9607563cba137b2e1a63e996a05d43ff603e
Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
Diffstat (limited to 'src/gui/image/qimage.cpp')
-rw-r--r-- | src/gui/image/qimage.cpp | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 097033280a..96a1b38d48 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -3261,14 +3261,31 @@ QImage QImage::rgbSwapped_helper() const res.d->colortable[i] = QRgb(((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00)); } break; - case Format_RGB32: - case Format_ARGB32: - case Format_ARGB32_Premultiplied: -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN case Format_RGBX8888: case Format_RGBA8888: case Format_RGBA8888_Premultiplied: +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + 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) { + uint c = *p; + *q = ((c << 16) & 0xff000000) | ((c >> 16) & 0xff00) | (c & 0x00ff00ff); + p++; + q++; + } + } + break; +#else + // On little-endian rgba8888 is abgr32 and can use same rgb-swap as argb32 + Q_FALLTHROUGH(); #endif + case Format_RGB32: + case Format_ARGB32: + case Format_ARGB32_Premultiplied: res = QImage(d->width, d->height, d->format); QIMAGE_SANITYCHECK_MEMORY(res); for (int i = 0; i < d->height; i++) { @@ -3352,14 +3369,27 @@ void QImage::rgbSwapped_inplace() d->colortable[i] = QRgb(((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00)); } break; - case Format_RGB32: - case Format_ARGB32: - case Format_ARGB32_Premultiplied: -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN case Format_RGBX8888: case Format_RGBA8888: case Format_RGBA8888_Premultiplied: +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + for (int i = 0; i < d->height; i++) { + uint *p = (uint*)scanLine(i); + uint *end = p + d->width; + while (p < end) { + uint c = *p; + *p = ((c << 16) & 0xff000000) | ((c >> 16) & 0xff00) | (c & 0x00ff00ff); + p++; + } + } + break; +#else + // On little-endian rgba8888 is abgr32 and can use same rgb-swap as argb32 + Q_FALLTHROUGH(); #endif + case Format_RGB32: + case Format_ARGB32: + case Format_ARGB32_Premultiplied: for (int i = 0; i < d->height; i++) { uint *p = (uint*)scanLine(i); uint *end = p + d->width; |