The BITMAPINFO
structure has the following declaration
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
It is a standard trick to declare a variable sized struct. The color table never has just one entry, it has at least 2 for a monochrome bitmap, typically 256 for a 8bpp bitmap, etc. Indicated by the bmiHeader.biClrUsed member. So the actual size of the struct depends on the bitmap format.
Since the C language doesn't permit declaring such a data structure, this is the closest match. Creating the structure requires malloc() to allocate sufficient bytes to store the structure, calculated from biClrUsed. Then a simple cast to (BITMAPINFO*) makes it usable.
It doesn't matter than it is static or not. The thing is, you'd still have to allocate enough memory for the palette. It is a RGBQuad because it stores only R, G, B, A and nothing more..
example:
for(i = 0; i < 256; i++)
{
lpbmpinfo->bmiColors[i].rgbRed = some_r;
lpbmpinfo->bmiColors[i].rgbGreen = some_g;
lpbmpinfo->bmiColors[i].rgbBlue = some_b;
lpbmpinfo->bmiColors[i].rgbReserved = 0;
}
There's no static
keyword in the declaration. It's a completely normal struct member. It's used to declare a variable-sized struct with a single variable-sized array at the end
The size of the array is only known at compile time, but since arrays of size 0 are forbidden in C and C++ so we'll use array[1]
instead. See the detailed explanation from MS' Raymond Chen in Why do some structures end with an array of size 1?
On some compilers like GCC zero-length arrays are allowed as an extension so Linux and many other platforms usually use array[0]
instead of array[1]
Declaring zero-length arrays is allowed in GNU C as an extension. A zero-length array can be useful as the last element of a structure that is really a header for a variable-length object:
struct line { int length; char contents[0]; }; struct line *thisline = (struct line *) malloc (sizeof (struct line) + this_length); thisline->length = this_length;
Arrays of Length Zero
In C99 a new feature called flexible array member was introduced. Since then it's better to use array[]
for portability
struct vectord {
size_t len;
double arr[]; // the flexible array member must be last
};
See also