Xteink-X4-crosspoint-reader/lib/GfxRenderer/Bitmap.h
Eunchurn Park b5d92e71f7
Merge upstream/master into feature/continue-reading-cover
Resolved merge conflicts:
- lib/Epub/Epub.h: Kept both upstream's cropped parameter and HEAD's thumb functions
- lib/JpegToBmpConverter/JpegToBmpConverter.cpp: Used upstream's version (dithering code moved to BitmapHelpers)
- src/activities/home/HomeActivity.cpp: Kept HEAD's comment about stack size

Added missing 1-bit dithering support to BitmapHelpers:
- Added Atkinson1BitDitherer class to BitmapHelpers.h
- Added quantize1bit() function to BitmapHelpers.cpp
2026-01-14 02:24:36 +09:00

70 lines
1.6 KiB
C++

#pragma once
#include <SdFat.h>
#include <cstdint>
#include "BitmapHelpers.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, bool dithering = false) : file(file), dithering(dithering) {}
~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;
bool dithering = false;
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
mutable AtkinsonDitherer* atkinsonDitherer = nullptr;
mutable FloydSteinbergDitherer* fsDitherer = nullptr;
};