mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-06 23:57:39 +03:00
72 lines
2.5 KiB
C++
72 lines
2.5 KiB
C++
#pragma once
|
|
|
|
#include <Print.h>
|
|
|
|
#include <cstdint>
|
|
|
|
// ============================================================================
|
|
// BMP WRITING HELPERS
|
|
// ============================================================================
|
|
|
|
// Write 16-bit value in little-endian format
|
|
inline void write16(Print& out, const uint16_t value) {
|
|
out.write(value & 0xFF);
|
|
out.write((value >> 8) & 0xFF);
|
|
}
|
|
|
|
// Write 32-bit unsigned value in little-endian format
|
|
inline void write32(Print& out, const uint32_t value) {
|
|
out.write(value & 0xFF);
|
|
out.write((value >> 8) & 0xFF);
|
|
out.write((value >> 16) & 0xFF);
|
|
out.write((value >> 24) & 0xFF);
|
|
}
|
|
|
|
// Write 32-bit signed value in little-endian format
|
|
inline void write32Signed(Print& out, const int32_t value) {
|
|
out.write(value & 0xFF);
|
|
out.write((value >> 8) & 0xFF);
|
|
out.write((value >> 16) & 0xFF);
|
|
out.write((value >> 24) & 0xFF);
|
|
}
|
|
|
|
// Write BMP header with 2-bit color depth (4-level grayscale)
|
|
static inline void writeBmpHeader2bit(Print& bmpOut, const int width, const int height) {
|
|
// Calculate row padding (each row must be multiple of 4 bytes)
|
|
const int bytesPerRow = (width * 2 + 31) / 32 * 4; // 2 bits per pixel, round up
|
|
const int imageSize = bytesPerRow * height;
|
|
const uint32_t fileSize = 70 + imageSize; // 14 (file header) + 40 (DIB header) + 16 (palette) + image
|
|
|
|
// BMP File Header (14 bytes)
|
|
bmpOut.write('B');
|
|
bmpOut.write('M');
|
|
write32(bmpOut, fileSize); // File size
|
|
write32(bmpOut, 0); // Reserved
|
|
write32(bmpOut, 70); // Offset to pixel data
|
|
|
|
// DIB Header (BITMAPINFOHEADER - 40 bytes)
|
|
write32(bmpOut, 40);
|
|
write32Signed(bmpOut, width);
|
|
write32Signed(bmpOut, -height); // Negative height = top-down bitmap
|
|
write16(bmpOut, 1); // Color planes
|
|
write16(bmpOut, 2); // Bits per pixel (2 bits)
|
|
write32(bmpOut, 0); // BI_RGB (no compression)
|
|
write32(bmpOut, imageSize);
|
|
write32(bmpOut, 2835); // xPixelsPerMeter (72 DPI)
|
|
write32(bmpOut, 2835); // yPixelsPerMeter (72 DPI)
|
|
write32(bmpOut, 4); // colorsUsed
|
|
write32(bmpOut, 4); // colorsImportant
|
|
|
|
// Color Palette (4 colors x 4 bytes = 16 bytes)
|
|
// Format: Blue, Green, Red, Reserved (BGRA)
|
|
uint8_t palette[16] = {
|
|
0x00, 0x00, 0x00, 0x00, // Color 0: Black
|
|
0x55, 0x55, 0x55, 0x00, // Color 1: Dark gray (85)
|
|
0xAA, 0xAA, 0xAA, 0x00, // Color 2: Light gray (170)
|
|
0xFF, 0xFF, 0xFF, 0x00 // Color 3: White
|
|
};
|
|
for (const uint8_t i : palette) {
|
|
bmpOut.write(i);
|
|
}
|
|
}
|