Skip to content

Commit 316adda

Browse files
committed
Add bias value to image dithering
1 parent cbb736f commit 316adda

File tree

5 files changed

+31
-24
lines changed

5 files changed

+31
-24
lines changed

src/include/Image.h

Lines changed: 2 additions & 2 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);
113+
uint8_t findClosestPalette(uint32_t c, uint16_t bias);
114114

115115
private:
116116
virtual void startWrite(void) = 0;
@@ -202,4 +202,4 @@ class Image : virtual public NetworkClient, virtual public Adafruit_GFX
202202
// -------------------------------------------
203203
};
204204

205-
#endif
205+
#endif

src/include/ImageBMP.cpp

Lines changed: 4 additions & 11 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) << (i & 1 ? 0 : 4);
115+
palette[i >> 1] |= findClosestPalette(c, 0) << (i & 1 ? 0 : 4);
116116
ditherPalette[i] = c;
117117
#else
118118
uint8_t r = (c & 0xFF000000) >> 24;
@@ -411,13 +411,6 @@ void Image::displayBmpLine(int16_t x, int16_t y, bitmapHeader *bmpHeader, bool d
411411
val = RGB3BIT(r, g, b);
412412
#endif
413413
}
414-
415-
#if defined(ARDUINO_INKPLATECOLOR) || defined(ARDUINO_INKPLATE2) || defined(ARDUINO_INKPLATE4) || \
416-
defined(ARDUINO_INKPLATE7)
417-
val = findClosestPalette((r << 16) | (g << 8) | (b));
418-
#else
419-
val = RGB3BIT(r, g, b);
420-
#endif
421414
writePixel(x + j, (h - y - 1), val);
422415
break;
423416
}
@@ -439,7 +432,7 @@ void Image::displayBmpLine(int16_t x, int16_t y, bitmapHeader *bmpHeader, bool d
439432
{
440433
#if defined(ARDUINO_INKPLATECOLOR) || defined(ARDUINO_INKPLATE2) || defined(ARDUINO_INKPLATE4) || \
441434
defined(ARDUINO_INKPLATE7)
442-
val = findClosestPalette((r << 16) | (g << 8) | (b));
435+
val = findClosestPalette((r << 16) | (g << 8) | (b), 0);
443436
#else
444437
val = RGB3BIT(r, g, b);
445438
#endif
@@ -474,7 +467,7 @@ void Image::displayBmpLine(int16_t x, int16_t y, bitmapHeader *bmpHeader, bool d
474467
{
475468
#if defined(ARDUINO_INKPLATECOLOR) || defined(ARDUINO_INKPLATE2) || defined(ARDUINO_INKPLATE4) || \
476469
defined(ARDUINO_INKPLATE7)
477-
val = findClosestPalette((r << 16) | (g << 8) | (b));
470+
val = findClosestPalette((r << 16) | (g << 8) | (b), 0);
478471
#else
479472
val = RGB3BIT(r, g, b);
480473
#endif
@@ -578,4 +571,4 @@ bool Image::drawBmpFromSdAtPosition(const char *fileName, const Position &positi
578571
}
579572

580573
return 1;
581-
}
574+
}

src/include/ImageDitherColor.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,32 @@ 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+
*
5660
* @return closest color in pallete array
5761
*/
58-
uint8_t Image::findClosestPalette(uint32_t c)
62+
uint8_t Image::findClosestPalette(uint32_t c, uint16_t bias)
5963
{
60-
int mi = 0;
61-
for (int i = 1; i < sizeof pallete / sizeof pallete[0]; ++i)
64+
int32_t minDistance = 0x7fffffff;
65+
uint8_t contenderCount = 0;
66+
uint8_t contenderList[sizeof pallete / sizeof pallete[0]];
67+
68+
for (int i = 0; i < sizeof pallete / sizeof pallete[0]; ++i)
6269
{
63-
if (COLORDISTSQR(c, pallete[i]) < COLORDISTSQR(c, pallete[mi]))
64-
mi = i;
70+
int32_t currentDistance = COLORDISTSQR(c, pallete[i]);
71+
if (currentDistance < minDistance) {
72+
minDistance = currentDistance;
73+
contenderList[0] = i;
74+
contenderCount = 1;
75+
} else if (currentDistance == minDistance) {
76+
contenderList[contenderCount] = i;
77+
contenderCount++;
78+
}
6579
}
6680

67-
return mi;
81+
return contenderList[bias % contenderCount];
6882
}
6983

7084
/**
@@ -100,7 +114,7 @@ uint8_t Image::ditherGetPixelBmp(uint32_t px, int i, int j, int w, bool paletted
100114
g = max((int16_t)0, min((int16_t)255, g));
101115
b = max((int16_t)0, min((int16_t)255, b));
102116

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

105119
int32_t rErr = r - (int32_t)((pallete[closest] >> 16) & 0xFF);
106120
int32_t gErr = g - (int32_t)((pallete[closest] >> 8) & 0xFF);

src/include/ImageJPEG.cpp

Lines changed: 2 additions & 2 deletions
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));
393+
val = _imagePtrJpeg->findClosestPalette(((uint32_t)r << 16) | ((uint32_t)g << 8) | ((uint32_t)b), 0);
394394
}
395395

396396
_imagePtrJpeg->writePixel(x + i, y + j, val);
@@ -421,4 +421,4 @@ bool Image::drawJpegChunk(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t
421421
#endif
422422

423423
return 1;
424-
}
424+
}

src/include/ImagePNG.cpp

Lines changed: 2 additions & 2 deletions
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));
80+
uint8_t px = _imagePtrPng->findClosestPalette((r << 16) | (g << 8) | (b), (_pngX + x + i) + (_pngY + y + j));
8181
#else
8282
uint8_t px = RGB3BIT(r, g, b);
8383
#endif
@@ -403,4 +403,4 @@ bool Image::drawPngFromSdAtPosition(const char *fileName, const Position &positi
403403
_pngPosition = _npos;
404404

405405
return ret;
406-
}
406+
}

0 commit comments

Comments
 (0)