3
votes

QImage has a constructor QImage (uchar *data, int width, int height, int bytesPerLine, Format format) that creates a QImage from an existing memory buffer.

Is the order of bytes (uchars) platform-dependent? If I put the values for alpha, red, green, and blue in it with increasing indices, alpha is swapped with blue and red is swapped with green. This indicates a problem with endian-ness.

I now wonder whether the endian-ness is platform-dependent or not. The Qt documentation does not say anything about this.

If it is NOT platform-dependent, I would just change the order of storing the values:

texture[ startIndex + 0 ] = pixelColor.blue();
texture[ startIndex + 1 ] = pixelColor.green();
texture[ startIndex + 2 ] = pixelColor.red();
texture[ startIndex + 3 ] = pixelColor.alpha();

If it is platform-dependent, I would create an array of uint32, store values computed as alpha << 24 | red << 16 | green << 8 | blue, and reinterpret_cast the array before passing it to the QImage() constructor.

Best regards,

Jens

2

2 Answers

2
votes

It depends on the format. Formats that state the total number of bits in a pixel are endian-dependent. Like Format_ARGB32 indicates a 32-bit integer whose highest 8 bits are alpha, which on a little endian machine, the same 8 bits are the last byte in the byte sequence.

Formats with individual bits in the sequence like Format_RGB888 are not endian-dependent. Format_RGB888 says the bytes are arranged in memory in R,G,B order regardless of endian.

To access bytes in the buffer, I would use Q_BYTE_ORDER macro to conditionally compile in the corresponding byte access code, instead of using shifts.

I personally use Format_RGB888 since I don't deal with alpha directly in the image. That saves me the problem of dealing with endian difference.

0
votes

From the Qt Docs:

Warning: If you are accessing 32-bpp image data, cast the returned pointer to QRgb* (QRgb has a 32-bit size) and use it to read/write the pixel value. You cannot use the uchar* pointer directly, because the pixel format depends on the byte order on the underlying platform. Use qRed(), qGreen(), qBlue(), and qAlpha() to access the pixels.