Improve EPUB cover image quality with pre-scaling and Atkinson dithering (#116)
## Summary * **What is the goal of this PR?** Replace simple threshold-based grayscale quantization with ordered dithering using a 4x4 Bayer matrix. This eliminates color banding artifacts and produces smoother gradients on e-ink display. * **What changes are included?** - Add 4x4 Bayer dithering matrix for 16-level threshold patterns - Modify `grayscaleTo2Bit()` function to accept pixel coordinates and apply position-based dithering - Replace simple `grayscale >> 6` threshold with ordered dithering algorithm that produces smoother gradients ## Additional Context * Bayer matrix approach: The 4x4 Bayer matrix creates a repeating pattern that distributes quantization error spatially, effectively simulating 16 levels of gray using only 4 actual color levels (black, dark gray, light gray, white). * Cache invalidation: Existing cached `cover.bmp` files will need to be deleted to see the improved rendering, as the converter only runs when the cache is missing.
This commit is contained in:
@@ -15,6 +15,7 @@ enum class BmpReaderError : uint8_t {
|
||||
UnsupportedCompression,
|
||||
|
||||
BadDimensions,
|
||||
ImageTooLarge,
|
||||
PaletteTooLarge,
|
||||
|
||||
SeekPixelDataFailed,
|
||||
@@ -28,8 +29,9 @@ class Bitmap {
|
||||
static const char* errorToString(BmpReaderError err);
|
||||
|
||||
explicit Bitmap(File& file) : file(file) {}
|
||||
~Bitmap();
|
||||
BmpReaderError parseHeaders();
|
||||
BmpReaderError readRow(uint8_t* data, uint8_t* rowBuffer) const;
|
||||
BmpReaderError readRow(uint8_t* data, uint8_t* rowBuffer, int rowY) const;
|
||||
BmpReaderError rewindToData() const;
|
||||
int getWidth() const { return width; }
|
||||
int getHeight() const { return height; }
|
||||
@@ -49,4 +51,9 @@ class Bitmap {
|
||||
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 lastRowY = -1; // Track row progression for error propagation
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user