Skip to content

Commit ff905d6

Browse files
committed
WIP: Increase resolution of dither buffer
1 parent 316adda commit ff905d6

File tree

7 files changed

+38
-47
lines changed

7 files changed

+38
-47
lines changed

src/include/Image.h

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class Image : virtual public NetworkClient, virtual public Adafruit_GFX
110110

111111
void getPointsForPosition(const Position &position, const uint16_t imageWidth, const uint16_t imageHeight,
112112
const uint16_t screenWidth, const uint16_t screenHeight, uint16_t *posX, uint16_t *posY);
113-
uint8_t findClosestPalette(uint32_t c, uint16_t bias);
113+
uint8_t findClosestPalette(int16_t r, int16_t g, int16_t b);
114114

115115
private:
116116
virtual void startWrite(void) = 0;
@@ -130,11 +130,7 @@ class Image : virtual public NetworkClient, virtual public Adafruit_GFX
130130
#endif
131131

132132
#if defined(ARDUINO_INKPLATECOLOR) || defined(ARDUINO_INKPLATE4) || defined(ARDUINO_INKPLATE7)
133-
int8_t ditherBuffer[3][16][E_INK_WIDTH + 20];
134-
135-
int8_t (*ditherBuffer_r)[E_INK_WIDTH + 20] = ditherBuffer[0];
136-
int8_t (*ditherBuffer_g)[E_INK_WIDTH + 20] = ditherBuffer[1];
137-
int8_t (*ditherBuffer_b)[E_INK_WIDTH + 20] = ditherBuffer[2];
133+
int32_t ditherBuffer[3][8][E_INK_WIDTH + 20];
138134

139135
const int kernelWidth = _kernelWidth;
140136
const int kernelHeight = _kernelHeight;
@@ -144,11 +140,7 @@ class Image : virtual public NetworkClient, virtual public Adafruit_GFX
144140

145141
const unsigned char (*kernel)[_kernelWidth] = _kernel;
146142
#elif ARDUINO_INKPLATE2
147-
int8_t ditherBuffer[3][16][E_INK_HEIGHT + 20];
148-
149-
int8_t (*ditherBuffer_r)[E_INK_HEIGHT + 20] = ditherBuffer[0];
150-
int8_t (*ditherBuffer_g)[E_INK_HEIGHT + 20] = ditherBuffer[1];
151-
int8_t (*ditherBuffer_b)[E_INK_HEIGHT + 20] = ditherBuffer[2];
143+
int32_t ditherBuffer[3][8][E_INK_WIDTH + 20];
152144

153145
const int kernelWidth = _kernelWidth;
154146
const int kernelHeight = _kernelHeight;

src/include/ImageBMP.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ void Image::readBmpHeader(uint8_t *buf, bitmapHeader *_h)
112112

113113
#if defined(ARDUINO_INKPLATECOLOR)
114114
c = c >> 8;
115-
palette[i >> 1] |= findClosestPalette(c, 0) << (i & 1 ? 0 : 4);
115+
palette[i >> 1] |= findClosestPalette(RED8(c), GREEN8(c), BLUE8(c)) << (i & 1 ? 0 : 4);
116116
ditherPalette[i] = c;
117117
#else
118118
uint8_t r = (c & 0xFF000000) >> 24;
@@ -432,7 +432,7 @@ void Image::displayBmpLine(int16_t x, int16_t y, bitmapHeader *bmpHeader, bool d
432432
{
433433
#if defined(ARDUINO_INKPLATECOLOR) || defined(ARDUINO_INKPLATE2) || defined(ARDUINO_INKPLATE4) || \
434434
defined(ARDUINO_INKPLATE7)
435-
val = findClosestPalette((r << 16) | (g << 8) | (b), 0);
435+
val = findClosestPalette(r, g, b);
436436
#else
437437
val = RGB3BIT(r, g, b);
438438
#endif
@@ -467,7 +467,7 @@ void Image::displayBmpLine(int16_t x, int16_t y, bitmapHeader *bmpHeader, bool d
467467
{
468468
#if defined(ARDUINO_INKPLATECOLOR) || defined(ARDUINO_INKPLATE2) || defined(ARDUINO_INKPLATE4) || \
469469
defined(ARDUINO_INKPLATE7)
470-
val = findClosestPalette((r << 16) | (g << 8) | (b), 0);
470+
val = findClosestPalette(r, g, b);
471471
#else
472472
val = RGB3BIT(r, g, b);
473473
#endif

src/include/ImageDitherColor.cpp

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,20 @@ static unsigned int width = E_INK_WIDTH, height = E_INK_HEIGHT;
5353
* @param uint32_t c
5454
* color of the given pixel
5555
*
56-
* @param uint16_t bias
57-
* an arbitrary value used to break ties, should be different
58-
* for neighboring pixels, and should ideally be random
59-
*
6056
* @return closest color in pallete array
6157
*/
62-
uint8_t Image::findClosestPalette(uint32_t c, uint16_t bias)
58+
uint8_t Image::findClosestPalette(int16_t r, int16_t g, int16_t b)
6359
{
64-
int32_t minDistance = 0x7fffffff;
60+
int64_t minDistance = 0x7fffffffffffffff;
6561
uint8_t contenderCount = 0;
6662
uint8_t contenderList[sizeof pallete / sizeof pallete[0]];
6763

6864
for (int i = 0; i < sizeof pallete / sizeof pallete[0]; ++i)
6965
{
70-
int32_t currentDistance = COLORDISTSQR(c, pallete[i]);
66+
int16_t pr = RED8(pallete[i]);
67+
int16_t pg = GREEN8(pallete[i]);
68+
int16_t pb = BLUE8(pallete[i]);
69+
int64_t currentDistance = SQR(r - pr) + SQR(g - pg) + SQR(b - pb);
7170
if (currentDistance < minDistance) {
7271
minDistance = currentDistance;
7372
contenderList[0] = i;
@@ -78,7 +77,7 @@ uint8_t Image::findClosestPalette(uint32_t c, uint16_t bias)
7877
}
7978
}
8079

81-
return contenderList[bias % contenderCount];
80+
return contenderList[contenderCount <= 1 ? 0 : rand() % contenderCount];
8281
}
8382

8483
/**
@@ -102,19 +101,19 @@ uint8_t Image::ditherGetPixelBmp(uint32_t px, int i, int j, int w, bool paletted
102101
if (paletted)
103102
px = ditherPalette[px];
104103

105-
int16_t r = RED8(px) + ditherBuffer[0][j % 15][i];
106-
int16_t g = GREEN8(px) + ditherBuffer[1][j % 15][i];
107-
int16_t b = BLUE8(px) + ditherBuffer[2][j % 15][i];
104+
int16_t r = RED8(px) + ditherBuffer[0][j % 8][i] / coef;
105+
int16_t g = GREEN8(px) + ditherBuffer[1][j % 8][i] / coef;
106+
int16_t b = BLUE8(px) + ditherBuffer[2][j % 8][i] / coef;
108107

109-
ditherBuffer[0][j % 15][i] = 0;
110-
ditherBuffer[1][j % 15][i] = 0;
111-
ditherBuffer[2][j % 15][i] = 0;
108+
// r = max((int16_t)0, min((int16_t)255, r));
109+
// g = max((int16_t)0, min((int16_t)255, g));
110+
// b = max((int16_t)0, min((int16_t)255, b));
112111

113-
r = max((int16_t)0, min((int16_t)255, r));
114-
g = max((int16_t)0, min((int16_t)255, g));
115-
b = max((int16_t)0, min((int16_t)255, b));
112+
ditherBuffer[0][j % 8][i] = 0;
113+
ditherBuffer[1][j % 8][i] = 0;
114+
ditherBuffer[2][j % 8][i] = 0;
116115

117-
int closest = findClosestPalette(((uint32_t)r << 16) | ((uint32_t)g << 8) | ((uint32_t)b), i + j);
116+
int closest = findClosestPalette(r, g, b);
118117

119118
int32_t rErr = r - (int32_t)((pallete[closest] >> 16) & 0xFF);
120119
int32_t gErr = g - (int32_t)((pallete[closest] >> 8) & 0xFF);
@@ -126,9 +125,9 @@ uint8_t Image::ditherGetPixelBmp(uint32_t px, int i, int j, int w, bool paletted
126125
{
127126
if (!(0 <= i + l && i + l < w))
128127
continue;
129-
ditherBuffer[0][(j + k) % 15][i + l] += (kernel[k][l + kernelX] * rErr) / coef;
130-
ditherBuffer[1][(j + k) % 15][i + l] += (kernel[k][l + kernelX] * gErr) / coef;
131-
ditherBuffer[2][(j + k) % 15][i + l] += (kernel[k][l + kernelX] * bErr) / coef;
128+
ditherBuffer[0][(j + k) % 8][i + l] += (kernel[k][l + kernelX] * rErr);
129+
ditherBuffer[1][(j + k) % 8][i + l] += (kernel[k][l + kernelX] * gErr);
130+
ditherBuffer[2][(j + k) % 8][i + l] += (kernel[k][l + kernelX] * bErr);
132131
}
133132
}
134133

src/include/ImageDitherColorKernels.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@
2323
// one you want below
2424

2525
// Floyd Steinberg
26-
const int _coef = 16;
27-
const int _kernelX = 1;
28-
const unsigned char _kernel[3][4] = {
29-
{0, 0, 7},
30-
{3, 5, 1},
31-
};
26+
// const int _coef = 16;
27+
// const int _kernelX = 1;
28+
// const unsigned char _kernel[2][3] = {
29+
// {0, 0, 7},
30+
// {3, 5, 1},
31+
// };
3232

3333
/*
3434
//J F Jarvis, C N Judice, and W H Ninke "Minimized Average Error"
@@ -41,7 +41,7 @@ const unsigned char _kernel[3][5] = {
4141
};
4242
*/
4343

44-
/*
44+
4545
// Atkinson
4646
const int _coef = 8;
4747
const int _kernelX = 1;
@@ -50,7 +50,7 @@ const unsigned char _kernel[3][4] = {
5050
{1, 1, 1, 0},
5151
{0, 1, 0, 0},
5252
};
53-
*/
53+
5454

5555
/*
5656
// Burkes
@@ -87,4 +87,4 @@ const unsigned char _kernel[3][3] = {
8787
const int _kernelWidth = (sizeof _kernel[0] / sizeof _kernel[0][0]);
8888
const int _kernelHeight = (sizeof _kernel / sizeof _kernel[0]);
8989

90-
#endif
90+
#endif

src/include/ImageJPEG.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ bool Image::drawJpegChunk(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t
390390
}
391391
else
392392
{
393-
val = _imagePtrJpeg->findClosestPalette(((uint32_t)r << 16) | ((uint32_t)g << 8) | ((uint32_t)b), 0);
393+
val = _imagePtrJpeg->findClosestPalette(r, g, b);
394394
}
395395

396396
_imagePtrJpeg->writePixel(x + i, y + j, val);

src/include/ImagePNG.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ void pngle_on_draw(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t
7777
b = 255 - b;
7878
}
7979

80-
uint8_t px = _imagePtrPng->findClosestPalette((r << 16) | (g << 8) | (b), (_pngX + x + i) + (_pngY + y + j));
80+
uint8_t px = _imagePtrPng->findClosestPalette(r, g, b);
8181
#else
8282
uint8_t px = RGB3BIT(r, g, b);
8383
#endif

src/include/defines.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@
199199

200200
#define DATA 0x0E8C0030
201201

202-
#define SQR(a) ((int32_t)(a) * (int32_t)(a))
202+
#define SQR(a) ((int64_t)(a) * (int64_t)(a))
203203
#define COLORDISTSQR(x, y) (SQR(RED8(x) - RED8(y)) + SQR(GREEN8(x) - GREEN8(y)) + SQR(BLUE8(x) - BLUE8(y)))
204204

205205
#endif

0 commit comments

Comments
 (0)