1

The BITMAPINFO structure has the following declaration

typedef struct tagBITMAPINFO {
    BITMAPINFOHEADER bmiHeader;
    RGBQUAD bmiColors[1];
} BITMAPINFO;

Why is the RGBQUAD array static? Why is it not a pointer?

phuclv
  • 37,963
  • 15
  • 156
  • 475

3 Answers3

5

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.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
0

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;
}
Brandon
  • 22,723
  • 11
  • 93
  • 186
  • I understand it. I thought to use BITMAPINFO as a variable. Now I get it, thanks everybody) –  Feb 04 '14 at 18:21
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

phuclv
  • 37,963
  • 15
  • 156
  • 475