Bitmap.cpp 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #include "Bitmap.h"
  2. #include <cstring>
  3. #ifdef _WIN32
  4. #include <Windows.h>
  5. #else
  6. // for Linux platform, plz make sure the size of data type is correct for BMP spec.
  7. // if you use this on Windows or other platforms, plz pay attention to this.
  8. typedef int LONG;
  9. typedef unsigned char BYTE;
  10. typedef unsigned int DWORD;
  11. typedef unsigned short WORD;
  12. // __attribute__((packed)) on non-Intel arch may cause some unexpected error, plz be informed.
  13. typedef struct tagBITMAPFILEHEADER
  14. {
  15. WORD bfType; // 2 /* Magic identifier */
  16. DWORD bfSize; // 4 /* File size in bytes */
  17. WORD bfReserved1; // 2
  18. WORD bfReserved2; // 2
  19. DWORD bfOffBits; // 4 /* Offset to image data, bytes */
  20. } __attribute__((packed)) BITMAPFILEHEADER;
  21. typedef struct tagBITMAPINFOHEADER
  22. {
  23. DWORD biSize; // 4 /* Header size in bytes */
  24. LONG biWidth; // 4 /* Width of image */
  25. LONG biHeight; // 4 /* Height of image */
  26. WORD biPlanes; // 2 /* Number of colour planes */
  27. WORD biBitCount; // 2 /* Bits per pixel */
  28. DWORD biCompression; // 4 /* Compression type */
  29. DWORD biSizeImage; // 4 /* Image size in bytes */
  30. LONG biXPelsPerMeter; // 4
  31. LONG biYPelsPerMeter; // 4 /* Pixels per meter */
  32. DWORD biClrUsed; // 4 /* Number of colours */
  33. DWORD biClrImportant; // 4 /* Important colours */
  34. } __attribute__((packed)) BITMAPINFOHEADER;
  35. #endif
  36. #include <cstdlib>
  37. template struct Bitmap<RGBColor>;
  38. template<>
  39. template<>
  40. void Bitmap<RGBColor>::createPng<RGBColor>(const std::string& path) const
  41. {
  42. std::FILE* out = std::fopen(path.c_str(), "wb");
  43. BITMAPFILEHEADER bmfh;
  44. bmfh.bfType = 0x4d42;
  45. bmfh.bfSize = 14 + 40 + (width * height * 3);
  46. bmfh.bfReserved1 = 0;
  47. bmfh.bfReserved2 = 0;
  48. bmfh.bfOffBits = 14 + 40;
  49. BITMAPINFOHEADER bmih;
  50. memset(&bmih, 0, 40);
  51. bmih.biSize = 40;
  52. bmih.biWidth = width;
  53. bmih.biHeight = -long(height);
  54. bmih.biPlanes = 1;
  55. bmih.biBitCount = 24;
  56. bmih.biCompression = 0;
  57. std::fwrite(&bmfh, sizeof bmfh, 1, out);
  58. std::fwrite(&bmih, sizeof bmih, 1, out);
  59. size_t lineLength = (width * 3 + 3) & ~3;
  60. std::unique_ptr<unsigned char[]> linebuf = std::make_unique<unsigned char[]>(lineLength);
  61. memset(linebuf.get(), 0, lineLength);
  62. for (long i = 0; i < height; i++) {
  63. for (long j = 0; j < width; j++) {
  64. linebuf[j * 3 + 0] = pixels[i * height + j].b;
  65. linebuf[j * 3 + 1] = pixels[i * height + j].g;
  66. linebuf[j * 3 + 2] = pixels[i * height + j].r;
  67. }
  68. std::fwrite(linebuf.get(), 1, lineLength, out);
  69. }
  70. std::fclose(out);
  71. }