dosgame1/util/Gbm.cpp

69 lines
1.8 KiB
C++

#include "Gbm.h"
#include <cstdio>
#include "Files.h"
#define GBM_SIGNATURE 0x204d4247
Bitmap Gbm::loadFromMemory(const void *data, size_t size) {
// Check for minimum
if (size < sizeof (uint32_t) + sizeof (uint16_t) + sizeof (uint16_t) + 16 * 3) return {};
auto gbm = static_cast<const GbmHeader *>(data);
if (gbm->signature != GBM_SIGNATURE) return {};
if (gbm->width == 0 || gbm->height == 0) return {};
Bitmap bitmap(gbm->width, gbm->height);
for (auto i = 0; i < 16; i++) {
bitmap.SetPaletteEntry(i, {gbm->palette[i].r, gbm->palette[i].g, gbm->palette[i].b});
}
for (auto y = 0; y < gbm->height; y++) {
for (auto x = 0; x < gbm->width; x++) {
auto pv = gbm->data[y * gbm->width + x];
bitmap.SetPixel(x, y, pv);
}
}
return bitmap;
}
Bitmap Gbm::loadFromFile(const char *path) {
void *data;
auto len = Files::allocateBufferAndLoadFromFile(path, &data);
auto bitmap = loadFromMemory(data, len);
Files::deleteBuffer(data);
return bitmap;
}
void Gbm::writeToFile(const char *path, const Bitmap &bitmap) {
auto fp = fopen(path, "wb");
if (!fp) return;
// Write signature
uint32_t signature = GBM_SIGNATURE;
fwrite(&signature, 4, 1, fp);
uint16_t width = bitmap.GetWidth(), height = bitmap.GetHeight();
fwrite(&width, 2, 1, fp);
fwrite(&height, 2, 1, fp);
for (auto i = 0; i < 16; i++) {
auto entry = bitmap.GetPaletteEntry(i);
auto r = entry.r, g = entry.g, b = entry.b;
fwrite(&r, 1, 1, fp);
fwrite(&g, 1, 1, fp);
fwrite(&b, 1, 1, fp);
}
for (auto y = 0; y < height; y++) {
for (auto x = 0; x < width; x++) {
auto pv = bitmap.GetPixel(x, y);
fwrite(&pv, 1, 1, fp);
}
}
fclose(fp);
}