Files

104 lines
2.3 KiB
C++
Raw Permalink Normal View History

#pragma once
2026-02-08 21:29:14 +01:00
#include <HalStorage.h>
2026-01-12 12:36:19 +01:00
#include <cstdint>
#include "BitmapHelpers.h"
2026-02-22 04:22:32 +00:00
#pragma pack(push, 1)
struct BmpHeader {
struct {
uint16_t bfType;
uint32_t bfSize;
uint16_t bfReserved1;
uint16_t bfReserved2;
uint32_t bfOffBits;
} fileHeader;
struct {
uint32_t biSize;
int32_t biWidth;
int32_t biHeight;
uint16_t biPlanes;
uint16_t biBitCount;
uint32_t biCompression;
uint32_t biSizeImage;
int32_t biXPelsPerMeter;
int32_t biYPelsPerMeter;
uint32_t biClrUsed;
uint32_t biClrImportant;
} infoHeader;
struct RgbQuad {
uint8_t rgbBlue;
uint8_t rgbGreen;
uint8_t rgbRed;
uint8_t rgbReserved;
};
RgbQuad colors[2];
};
#pragma pack(pop)
enum class BmpReaderError : uint8_t {
Ok = 0,
FileInvalid,
SeekStartFailed,
NotBMP,
DIBTooSmall,
BadPlanes,
UnsupportedBpp,
UnsupportedCompression,
BadDimensions,
ImageTooLarge,
PaletteTooLarge,
SeekPixelDataFailed,
BufferTooSmall,
OomRowBuffer,
ShortReadRow,
};
class Bitmap {
public:
static const char* errorToString(BmpReaderError err);
2026-01-12 12:36:19 +01:00
explicit Bitmap(FsFile& file, bool dithering = false) : file(file), dithering(dithering) {}
~Bitmap();
BmpReaderError parseHeaders();
2026-01-05 11:07:27 +01:00
BmpReaderError readNextRow(uint8_t* data, uint8_t* rowBuffer) const;
BmpReaderError rewindToData() const;
int getWidth() const { return width; }
int getHeight() const { return height; }
bool isTopDown() const { return topDown; }
bool hasGreyscale() const { return bpp > 1; }
int getRowBytes() const { return rowBytes; }
bool is1Bit() const { return bpp == 1; }
uint16_t getBpp() const { return bpp; }
private:
2025-12-30 15:09:30 +10:00
static uint16_t readLE16(FsFile& f);
static uint32_t readLE32(FsFile& f);
2025-12-30 15:09:30 +10:00
FsFile& file;
2026-01-12 12:36:19 +01:00
bool dithering = false;
int width = 0;
int height = 0;
bool topDown = false;
uint32_t bfOffBits = 0;
uint16_t bpp = 0;
2026-02-19 12:33:29 +01:00
uint32_t colorsUsed = 0;
bool nativePalette = false; // true if all palette entries map to native gray levels
int rowBytes = 0;
uint8_t paletteLum[256] = {};
2026-02-19 12:33:29 +01:00
// Dithering state (mutable for const methods)
mutable int16_t* errorCurRow = nullptr;
mutable int16_t* errorNextRow = nullptr;
2026-01-05 11:07:27 +01:00
mutable int prevRowY = -1; // Track row progression for error propagation
2026-01-12 12:36:19 +01:00
mutable AtkinsonDitherer* atkinsonDitherer = nullptr;
mutable FloydSteinbergDitherer* fsDitherer = nullptr;
};