NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
The following reply was made to PR xsrc/59952; it has been noted by GNATS.
From: Valery Ushakov <uwe%stderr.spb.ru@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc:
Subject: Re: xsrc/59952: xsetwallpaper: server/client endian mismatch
Date: Wed, 4 Feb 2026 03:41:19 +0300
I'm not sure if the server is guaranteed to handle byte order other
than the ImageByteOrder it announces on the server side. But from a
very quick look it seems that xlib will take care of bswapping the
image as necessary. But instead of relying on someone doing that for
us it might be easier to just provide the image in the right odrder,
as we need to shuffle components anyway.
Something like that? Only very minimally tested.
--- xsetwallpaper.c.~1.4.~ 2026-02-03 00:03:28.073085100 +0300
+++ xsetwallpaper.c 2026-02-04 03:28:37.929559236 +0300
@@ -95,22 +95,6 @@ main(int argc, char *argv[])
data = stbi_load(argv[0], &imagew, &imageh, &imagebpp, 4);
if (data == NULL)
errx(EXIT_FAILURE, "failed to load %s", argv[0]);
-
- /* swap red and blue */
- for (i = 0; i < imagew * imageh * 4; i += 4) {
- uint8_t p;
- p = data[i + 0];
- data[i + 0] = data[i + 2];
- data[i + 2] = p;
- }
-
-#if _BYTE_ORDER == _BIG_ENDIAN
- for (i = 0; i < imagew * imageh * 4; i += 4) {
- uint32_t *p = (uint32_t *)&data[i];
- *p = bswap32(*p);
- }
-#endif
-
#ifdef DEBUG
printf("%s: %dx%d %dbpp\n", argv[0], imagew, imageh, imagebpp * 8);
#endif
@@ -126,6 +110,30 @@ main(int argc, char *argv[])
colormap = DefaultColormap(display, 0);
byte_order = ImageByteOrder(display);
+ /*
+ * stbi loads 4-component image as red, green, blue, alpha -
+ * i.e. little-endian ABGR. We need to provide it to the
+ * server in ARGB in ImageByteOrder(3).
+ */
+ enum { R, G, B, A };
+
+#if _BYTE_ORDER == _BIG_ENDIAN
+# define host_byte_order MSBFirst
+#else
+# define host_byte_order LSBFirst
+#endif
+ uint32_t *data32 = (uint32_t *)data;
+ for (i = 0; i < imagew * imageh; ++i) {
+ uint32_t pixel =
+ data[i*4 + A] << 24
+ | data[i*4 + R] << 16
+ | data[i*4 + G] << 8
+ | data[i*4 + B];
+ if (byte_order != host_byte_order)
+ pixel = bswap32(pixel);
+ data32[i] = pixel;
+ }
+
/* get root window geometry */
if (!XGetGeometry(display, XDefaultRootWindow(display), &window,
&root_x, &root_y, &root_width, &root_height,
-uwe
Home |
Main Index |
Thread Index |
Old Index