summaryrefslogtreecommitdiffstats
path: root/src/gui/image/qimage.cpp
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-07-05 13:04:26 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-10-02 08:06:21 +0000
commit6f16b7a8f33c9641850809562b627f9da12fa9ad (patch)
tree807dfa54222ce4b72e639f01285b494121211a93 /src/gui/image/qimage.cpp
parentb6f69206548f7bd15c72ba35d7c2e3b66b1abb7a (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.cpp46
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;