Question

I want to read, edit, and write bmp files without any external libraries, using just standard C.

If I understand correctly, it is important that bytes are properly aligned to match the bmp file format.

However, I think I have also read somewhere on the internet that the compiler is allowed to pad struct with extra bytes so I cannot always be sure exactly how many bytes my struct takes up, or even how the members are aligned within the struct.

How do I solve this issue using just standard C? Is there a syntax for asking the compiler to make sure my struct looks exactly the way I specify it?

Was it helpful?

Solution

How do I solve this issue using just standard C? Is there a syntax for asking the compiler to make sure my struct looks exactly the way I specify it?

The C standard does not provide a standard way to control struct layout. So, if you are dead set on only using what is specified by the standard, you cannot use structs to process Windows bitmap files.

To solve this using standard C you need to write/read byte arrays and serialize/deserialize them yourself.

OTHER TIPS

As Kninnug says in comments, the BMP format was designed to be compatible with C struct types. A C compiler is free to insert as much padding as it likes, for whatever reason it likes, between any two struct members or after the last member -- but in real life, compilers insert padding only where it's necessary for alignment, and often in conformance to a written ABI for the platform.

You can use the offsetof macro and the sizeof operator to test, but not to specify the layout of a struct type -- and that's probably good enough for your purposes.

For example, if you want a structure that conforms to an externally imposed layout consisting of a 32-bit unsigned integer, a 16-bit unsigned integer, and two 8-bit unsigned integers, allocated in that order for a total of 64 bits, you could write something like:

#include <stdint.h>
#include <stddef.h>
#include <assert.h>

struct s {
    uint32_t a;
    uint16_t b;
    uint8_t c;
    uint8_t d;
};

void test_layout(void) {
    assert(offsetof(struct s, a) == 0);
    assert(offsetof(struct s, b) == 4);
    assert(offsetof(struct s, c) == 6);
    assert(offsetof(struct s, d) == 7);
    assert(sizeof (struct s) == 8);
}

Call the test_layout() function when the program starts; if your program survives that, you can be assured that the layout is correct.

Well, almost -- testing byte order is left as an exercise.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top