§ Заголовочный файл

unsigned short - 16 бит
unsigned int   - 32 бит
1// Для выгрузки BMP https://ru.wikipedia.org/wiki/BMP
2
3// 14 байт
4struct __attribute__((__packed__)) BITMAPFILEHEADER {
5    unsigned short bfType;         // BM     Сигнатура
6    unsigned int   bfSize;         // 38518  Размер файла BMP
7    unsigned short bfReserved1;    // 0
8    unsigned short bfReserved2;    // 0
9    unsigned int   bfOffBits;      // 0x76   Где начинаются данные
10};
11
12// 40 байт -- версия заголовка
13struct __attribute__((__packed__)) BITMAPINFOHEADER {
14    unsigned int   biSize;          // 0x28   Размер этого заголовка (40)
15    unsigned int   biWidth;         // 320    Размер по ширине
16    unsigned int   biHeight;        // 240    Размер по высоте
17    unsigned short biPlanes;        // 1      Количество битовых плоскостей (1)
18    unsigned short biBitCount;      // 4      Количество бит на пиксель (1,4,8,32)
19    unsigned int   biCompression;   // 0      Используемая компрессия
20    unsigned int   biSizeImage;     // 0x9600 (38400) = 320*240*0.5
21    unsigned int   biXPelsPerMeter; // 0x0B13 Разрешающая способность по X
22    unsigned int   biYPelsPerMeter; // 0x0B13 Разрешающая способность по Y
23    unsigned int   biClrUsed;       // 0x10   Количество используемых цветов (16)
24    unsigned int   biClrImportant;  // 0      Количество важных цветов (0 - все важны)
25};

§ Код для выгрузки BMP (16 Bit цвет)

  • framebuffer - это массив байтов (320x240x0.5)
  • Когда задается индексированная палитра (1,4 или 8 бит), то для нее обязательно строится таблица цветов
1struct BITMAPFILEHEADER head = {0x4D42, 38518, 0, 0, 0x76};
2struct BITMAPINFOHEADER info = {0x28, 320, 240, 1, 4, 0, 0x9600, 0xb13, 0xb13, 16, 0};
3
4unsigned char colors[64] =
5{
6   // R,  G,    B,    A
7    0x00, 0x00, 0x00, 0x00, // 0
8    0xc0, 0x00, 0x00, 0x00, // 1
9    0x00, 0x00, 0xc0, 0x00, // 2
10    0xc0, 0x00, 0xc0, 0x00, // 3
11    0x00, 0xc0, 0x00, 0x00, // 4
12    0xc0, 0xc0, 0x00, 0x00, // 5
13    0x00, 0xc0, 0xc0, 0x00, // 6
14    0xc0, 0xc0, 0xc0, 0x00, // 7
15    0x00, 0x00, 0x00, 0x00, // 8
16    0xff, 0x00, 0x00, 0x00, // 9
17    0x00, 0x00, 0xff, 0x00, // 10
18    0xff, 0x00, 0xff, 0x00, // 11
19    0x00, 0xff, 0x00, 0x00, // 12
20    0xff, 0xff, 0x00, 0x00, // 13
21    0x00, 0xff, 0xff, 0x00, // 14
22    0xff, 0xff, 0xff, 0x00  // 15
23};
24
25FILE* fp = fopen("output.bmp", "wb");
26fwrite(&head, 1, sizeof(struct BITMAPFILEHEADER), fp);
27fwrite(&info, 1, sizeof(struct BITMAPINFOHEADER), fp);
28fwrite(&colors, 1, 64, record_file);
29fwrite(framebuffer, 1, 160*240, fp);
30fclose(fp);

§ Важная особенность

При записи в BMP, записывать надо сначала последнюю строку, и по убыванию. То есть, вначале идет самая последняя строка изображения (сверху вниз), но по горизонтали всё в порядке (слева направо).