Xteink-X4-crosspoint-reader/lib/GfxRenderer/Bitmap.h
Eunchurn Park 0f9f8d71d9
Merge upstream/master into feature/continue-reading-cover
Resolve conflicts:
- GfxRenderer: Add cropX/cropY params to drawBitmap, keep 1-bit BMP support
- GfxRenderer: Update drawBitmap1Bit to use readNextRow (API change)
- JpegToBmpConverter: Use upstream scaling logic (larger dimension)
- HomeActivity: Use StringUtils::checkFileExtension, add hasOpdsUrl
- HomeActivity: Keep cover image functionality with own buffer management
2026-01-09 23:57:38 +09:00

62 lines
1.4 KiB
C++

#pragma once
#include <SdFat.h>
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);
explicit Bitmap(FsFile& file) : file(file) {}
~Bitmap();
BmpReaderError parseHeaders();
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:
static uint16_t readLE16(FsFile& f);
static uint32_t readLE32(FsFile& f);
FsFile& file;
int width = 0;
int height = 0;
bool topDown = false;
uint32_t bfOffBits = 0;
uint16_t bpp = 0;
int rowBytes = 0;
uint8_t paletteLum[256] = {};
// Floyd-Steinberg dithering state (mutable for const methods)
mutable int16_t* errorCurRow = nullptr;
mutable int16_t* errorNextRow = nullptr;
mutable int prevRowY = -1; // Track row progression for error propagation
};