Skip to content

Commit 776383c

Browse files
committed
Inky 7.3: Add ordered dither support.
1 parent 88e5089 commit 776383c

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

libraries/pico_graphics/pico_graphics.hpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,32 @@ namespace pimoroni {
499499

500500
class PicoGraphics_PenInky7 : public PicoGraphics {
501501
public:
502+
static const uint16_t palette_size = 8;
503+
RGB palette[8] = {
504+
/*
505+
{0x2b, 0x2a, 0x37},
506+
{0xdc, 0xcb, 0xba},
507+
{0x35, 0x56, 0x33},
508+
{0x33, 0x31, 0x47},
509+
{0x9c, 0x3b, 0x2e},
510+
{0xd3, 0xa9, 0x34},
511+
{0xab, 0x58, 0x37},
512+
{0xb2, 0x8e, 0x67}
513+
*/
514+
{ 0, 0, 0}, // black
515+
{255, 255, 255}, // white
516+
{ 0, 255, 0}, // green
517+
{ 0, 0, 255}, // blue
518+
{255, 0, 0}, // red
519+
{255, 255, 0}, // yellow
520+
{255, 128, 0}, // orange
521+
{220, 180, 200} // clean / taupe?!
522+
};
523+
524+
std::array<std::array<uint8_t, 16>, 512> candidate_cache;
525+
bool cache_built = false;
526+
std::array<uint8_t, 16> candidates;
527+
502528
RGB src_color;
503529
RGB565 color;
504530
IDirectDisplayDriver<uint8_t> &driver;
@@ -510,6 +536,10 @@ namespace pimoroni {
510536
int create_pen(uint8_t r, uint8_t g, uint8_t b) override;
511537
void set_pixel(const Point &p) override;
512538
void set_pixel_span(const Point &p, uint l) override;
539+
540+
void get_dither_candidates(const RGB &col, const RGB *palette, size_t len, std::array<uint8_t, 16> &candidates);
541+
void set_pixel_dither(const Point &p, const RGB &c) override;
542+
513543
void frame_convert(PenType type, conversion_callback_func callback) override;
514544
static size_t buffer_size(uint w, uint h) {
515545
return w * h;

libraries/pico_graphics/pico_graphics_pen_inky7.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,49 @@ namespace pimoroni {
2020
void PicoGraphics_PenInky7::set_pixel_span(const Point &p, uint l) {
2121
driver.write_pixel_span(p, l, color);
2222
}
23+
void PicoGraphics_PenInky7::get_dither_candidates(const RGB &col, const RGB *palette, size_t len, std::array<uint8_t, 16> &candidates) {
24+
RGB error;
25+
for(size_t i = 0; i < candidates.size(); i++) {
26+
candidates[i] = (col + error).closest(palette, len);
27+
error += (col - palette[candidates[i]]);
28+
}
29+
30+
// sort by a rough approximation of luminance, this ensures that neighbouring
31+
// pixels in the dither matrix are at extreme opposites of luminence
32+
// giving a more balanced output
33+
std::sort(candidates.begin(), candidates.end(), [palette](int a, int b) {
34+
return palette[a].luminance() > palette[b].luminance();
35+
});
36+
}
37+
void PicoGraphics_PenInky7::set_pixel_dither(const Point &p, const RGB &c) {
38+
if(!bounds.contains(p)) return;
39+
40+
if(!cache_built) {
41+
for(uint i = 0; i < 512; i++) {
42+
uint r = (i & 0x1c0) >> 1;
43+
uint g = (i & 0x38) << 2;
44+
uint b = (i & 0x7) << 5;
45+
RGB cache_col(
46+
r | (r >> 3) | (r >> 6),
47+
g | (g >> 3) | (g >> 6),
48+
b | (b >> 3) | (b >> 6)
49+
);
50+
get_dither_candidates(cache_col, palette, palette_size, candidate_cache[i]);
51+
}
52+
cache_built = true;
53+
}
54+
55+
uint cache_key = ((c.r & 0xE0) << 1) | ((c.g & 0xE0) >> 2) | ((c.b & 0xE0) >> 5);
56+
//get_dither_candidates(c, palette, 256, candidates);
57+
58+
// find the pattern coordinate offset
59+
uint pattern_index = (p.x & 0b11) | ((p.y & 0b11) << 2);
60+
61+
// set the pixel
62+
//color = candidates[pattern[pattern_index]];
63+
color = candidate_cache[cache_key][dither16_pattern[pattern_index]];
64+
set_pixel(p);
65+
}
2366
void PicoGraphics_PenInky7::frame_convert(PenType type, conversion_callback_func callback) {
2467
if(type == PEN_INKY7) {
2568
uint byte_count = bounds.w/2;

0 commit comments

Comments
 (0)