// Create a 24 bit BMP file with R G B color

#include <iostream>
#include <string>
#include <fstream>
#include <cstdio>

int main(int argc, char** argv) {
  if (argc != 7) {
    std::fprintf(stderr, "Syntax: %s Width Height R G B outputFile\n", argv[0]);
    return 1;
  }
  unsigned long long ww = std::stoull(argv[1]);
  unsigned long long hh = std::stoull(argv[2]);
  unsigned char rr = static_cast<unsigned char>(std::stoi(argv[3]));
  unsigned char gg = static_cast<unsigned char>(std::stoi(argv[4]));
  unsigned char bb = static_cast<unsigned char>(std::stoi(argv[5]));

  int nBytesPaddingPerRow = (3*ww%4 == 0) ? 0 : (4 - 3*ww%4);
  unsigned long long restSize = 3*ww*hh + hh*nBytesPaddingPerRow;
  unsigned long long fileSize = restSize + 54;

  unsigned char header[54] = {0};
  header[0] = 66;
  header[1] = 77;
  header[10] = 54;
  header[14] = 40;
  header[26] = 1;
  header[28] = 24;

  header[2] = *(reinterpret_cast<unsigned char *>(&fileSize) + 0); // File Size byte 0 (LSB)
  header[3] = *(reinterpret_cast<unsigned char *>(&fileSize) + 1); // File Size byte 1
  header[4] = *(reinterpret_cast<unsigned char *>(&fileSize) + 2); // File Size byte 2
  header[5] = *(reinterpret_cast<unsigned char *>(&fileSize) + 3); // File Size byte 3 (MSB)

  header[18] = *(reinterpret_cast<unsigned char *>(&ww) + 0); // Width byte 0 (LSB)
  header[19] = *(reinterpret_cast<unsigned char *>(&ww) + 1); // Width byte 1
  header[20] = *(reinterpret_cast<unsigned char *>(&ww) + 2); // Width byte 2
  header[21] = *(reinterpret_cast<unsigned char *>(&ww) + 3); // Width byte 3 (MSB)

  header[22] = *(reinterpret_cast<unsigned char *>(&hh) + 0); // Height byte 0 (LSB)
  header[23] = *(reinterpret_cast<unsigned char *>(&hh) + 1); // Height byte 1
  header[24] = *(reinterpret_cast<unsigned char *>(&hh) + 2); // Height byte 2
  header[25] = *(reinterpret_cast<unsigned char *>(&hh) + 3); // Height byte 3 (MSB)

  header[34] = *(reinterpret_cast<unsigned char *>(&restSize) + 0); // Rest Size byte 0 (LSB)
  header[35] = *(reinterpret_cast<unsigned char *>(&restSize) + 1); // Rest Size byte 1
  header[36] = *(reinterpret_cast<unsigned char *>(&restSize) + 2); // Rest Size byte 2
  header[37] = *(reinterpret_cast<unsigned char *>(&restSize) + 3); // Rest Size byte 3 (MSB)

  std::ofstream fout(argv[6], std::ios::out | std::ios::binary);

  fout.write(reinterpret_cast<char *>(&header[0]), 54);

  unsigned long long yy;
  unsigned long long xx;
  for (yy = 0; yy < hh; yy++) {
    for (xx = 0; xx < ww; xx++) {
      fout << bb; // PixelArray[yy][xx][Blue]
      fout << gg; // PixelArray[yy][xx][Green]
      fout << rr; // PixelArray[yy][xx][Red]
    }
    for (xx = 0; xx < nBytesPaddingPerRow; xx++) {
      fout << '\x0';
    }
  }

  fout.close();
  return 0;
}
      

// Generated by xformulas.net on 20190910_091836