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

unsigned short - 16 бит
unsigned int   - 32 бит
// Для выгрузки BMP https://ru.wikipedia.org/wiki/BMP

// 14 байт
struct __attribute__((__packed__)) BITMAPFILEHEADER {
    unsigned short bfType;         // BM     Сигнатура
    unsigned int   bfSize;         // 38518  Размер файла BMP
    unsigned short bfReserved1;    // 0
    unsigned short bfReserved2;    // 0
    unsigned int   bfOffBits;      // 0x76   Где начинаются данные
};

// 40 байт -- версия заголовка
struct __attribute__((__packed__)) BITMAPINFOHEADER {
    unsigned int   biSize;          // 0x28   Размер этого заголовка (40)
    unsigned int   biWidth;         // 320    Размер по ширине
    unsigned int   biHeight;        // 240    Размер по высоте
    unsigned short biPlanes;        // 1      Количество битовых плоскостей (1)
    unsigned short biBitCount;      // 4      Количество бит на пиксель (1,4,8,32)
    unsigned int   biCompression;   // 0      Используемая компрессия
    unsigned int   biSizeImage;     // 0x9600 (38400) = 320*240*0.5
    unsigned int   biXPelsPerMeter; // 0x0B13 Разрешающая способность по X
    unsigned int   biYPelsPerMeter; // 0x0B13 Разрешающая способность по Y
    unsigned int   biClrUsed;       // 0x10   Количество используемых цветов (16)
    unsigned int   biClrImportant;  // 0      Количество важных цветов (0 - все важны)
};

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

  • framebuffer - это массив байтов (320x240x0.5)
  • Когда задается индексированная палитра (1,4 или 8 бит), то для нее обязательно строится таблица цветов
struct BITMAPFILEHEADER head = {0x4D42, 38518, 0, 0, 0x76};
struct BITMAPINFOHEADER info = {0x28, 320, 240, 1, 4, 0, 0x9600, 0xb13, 0xb13, 16, 0};

unsigned char colors[64] =
{
   // R,  G,    B,    A
    0x00, 0x00, 0x00, 0x00, // 0
    0xc0, 0x00, 0x00, 0x00, // 1
    0x00, 0x00, 0xc0, 0x00, // 2
    0xc0, 0x00, 0xc0, 0x00, // 3
    0x00, 0xc0, 0x00, 0x00, // 4
    0xc0, 0xc0, 0x00, 0x00, // 5
    0x00, 0xc0, 0xc0, 0x00, // 6
    0xc0, 0xc0, 0xc0, 0x00, // 7
    0x00, 0x00, 0x00, 0x00, // 8
    0xff, 0x00, 0x00, 0x00, // 9
    0x00, 0x00, 0xff, 0x00, // 10
    0xff, 0x00, 0xff, 0x00, // 11
    0x00, 0xff, 0x00, 0x00, // 12
    0xff, 0xff, 0x00, 0x00, // 13
    0x00, 0xff, 0xff, 0x00, // 14
    0xff, 0xff, 0xff, 0x00  // 15
};

FILE* fp = fopen("output.bmp", "wb");
fwrite(&head, 1, sizeof(struct BITMAPFILEHEADER), fp);
fwrite(&info, 1, sizeof(struct BITMAPINFOHEADER), fp);
fwrite(&colors, 1, 64, record_file);
fwrite(framebuffer, 1, 160*240, fp);
fclose(fp);

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

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