69 lines
1.8 KiB
C++
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);
|
|
}
|