Creating a QBitmap
from raw data stored in the XBM format, can easily be done like so QBitmap::fromData(width, height, data, QImage::Format_MonoLSB)
,
with data
being the raw data of the XBM file.
Now, what if we want to create a QImage
this time? Indeed, say we want to create a QImage
from the same XBM raw data.
One additional constraint though: no QBitmap
should be used here, meaning converting a QBitmap
to get a QImage
would not be an acceptable solution.
I tried QImage(data, width, height, QImage::Format_MonoLSB)
but it doesn't produce the proper image since QImage
expects bits to be 32-bits aligned, cf. Qt's 4.8 documentation:
QImage::QImage(uchar * data, int width, int height, Format format)
Constructs an image with the given width, height and format, that uses an existing memory buffer, data. The width and height must be specified in pixels, data must be 32-bit aligned, and each scanline of data in the image must also be 32-bit aligned.
The issue is the XBM is 1-bit aligned (not 32-bits aligned), therefore the QImage
produced by QImage(data, width, height, QImage::Format_MonoLSB)
is garbage (undefined behavior, "random" image).
So, how to create a QImage
from the raw data
of an XBM?
EDIT: Here's an XBM file with which a QImage should constructed:
#define x_width 66
#define x_height 27
static char x_bits[] = {
0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, ...
};
Ok, so it turns out that Qt alreay has implemented a simple code that builds a QImage
from the raw data of an XBM
:
QImage image(size, monoFormat);
image.setColor(0, QColor(Qt::color0).rgb());
image.setColor(1, QColor(Qt::color1).rgb());
// Need to memcpy each line separatly since QImage is 32bit aligned and
// this data is only byte aligned...
int bytesPerLine = (size.width() + 7) / 8;
for (int y = 0; y < size.height(); ++y)
{
memcpy(image.scanLine(y), bits + bytesPerLine * y, bytesPerLine);
}
This code is used in qbitmap.cpp
, more specifically in:
QBitmap::fromData(const QSize &size, const uchar *bits, QImage::Format monoFormat)