1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- #include "Bitmap.h"
- #include <cstring>
- #ifdef _WIN32
- #include <Windows.h>
- #else
- // for Linux platform, plz make sure the size of data type is correct for BMP spec.
- // if you use this on Windows or other platforms, plz pay attention to this.
- typedef int LONG;
- typedef unsigned char BYTE;
- typedef unsigned int DWORD;
- typedef unsigned short WORD;
- // __attribute__((packed)) on non-Intel arch may cause some unexpected error, plz be informed.
- typedef struct tagBITMAPFILEHEADER
- {
- WORD bfType; // 2 /* Magic identifier */
- DWORD bfSize; // 4 /* File size in bytes */
- WORD bfReserved1; // 2
- WORD bfReserved2; // 2
- DWORD bfOffBits; // 4 /* Offset to image data, bytes */
- } __attribute__((packed)) BITMAPFILEHEADER;
- typedef struct tagBITMAPINFOHEADER
- {
- DWORD biSize; // 4 /* Header size in bytes */
- LONG biWidth; // 4 /* Width of image */
- LONG biHeight; // 4 /* Height of image */
- WORD biPlanes; // 2 /* Number of colour planes */
- WORD biBitCount; // 2 /* Bits per pixel */
- DWORD biCompression; // 4 /* Compression type */
- DWORD biSizeImage; // 4 /* Image size in bytes */
- LONG biXPelsPerMeter; // 4
- LONG biYPelsPerMeter; // 4 /* Pixels per meter */
- DWORD biClrUsed; // 4 /* Number of colours */
- DWORD biClrImportant; // 4 /* Important colours */
- } __attribute__((packed)) BITMAPINFOHEADER;
- #endif
- #include <cstdlib>
- template struct Bitmap<RGBColor>;
- template<>
- template<>
- void Bitmap<RGBColor>::createPng<RGBColor>(const std::string& path) const
- {
- std::FILE* out = std::fopen(path.c_str(), "wb");
- BITMAPFILEHEADER bmfh;
- bmfh.bfType = 0x4d42;
- bmfh.bfSize = 14 + 40 + (width * height * 3);
- bmfh.bfReserved1 = 0;
- bmfh.bfReserved2 = 0;
- bmfh.bfOffBits = 14 + 40;
- BITMAPINFOHEADER bmih;
- memset(&bmih, 0, 40);
- bmih.biSize = 40;
- bmih.biWidth = width;
- bmih.biHeight = -long(height);
- bmih.biPlanes = 1;
- bmih.biBitCount = 24;
- bmih.biCompression = 0;
- std::fwrite(&bmfh, sizeof bmfh, 1, out);
- std::fwrite(&bmih, sizeof bmih, 1, out);
- size_t lineLength = (width * 3 + 3) & ~3;
- std::unique_ptr<unsigned char[]> linebuf = std::make_unique<unsigned char[]>(lineLength);
- memset(linebuf.get(), 0, lineLength);
- for (long i = 0; i < height; i++) {
- for (long j = 0; j < width; j++) {
- linebuf[j * 3 + 0] = pixels[i * height + j].b;
- linebuf[j * 3 + 1] = pixels[i * height + j].g;
- linebuf[j * 3 + 2] = pixels[i * height + j].r;
- }
- std::fwrite(linebuf.get(), 1, lineLength, out);
- }
- std::fclose(out);
- }
|