From 12866a0b7b9bc6278f4034efaba0f34d38b33af0 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Wed, 6 Jul 2022 10:56:56 +0100 Subject: [PATCH] PicoGraphics/JPEGDEC: Use PicoGraphics dither. --- libraries/pico_graphics/pico_graphics.cpp | 1 + libraries/pico_graphics/pico_graphics.hpp | 3 +++ .../pico_graphics/pico_graphics_pen_1bit.cpp | 10 ++++++++ .../pico_graphics/pico_graphics_pen_1bitY.cpp | 10 ++++++++ micropython/modules/jpegdec/jpegdec.cpp | 24 ++++++++++--------- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/libraries/pico_graphics/pico_graphics.cpp b/libraries/pico_graphics/pico_graphics.cpp index 18674fef..0fc773dd 100644 --- a/libraries/pico_graphics/pico_graphics.cpp +++ b/libraries/pico_graphics/pico_graphics.cpp @@ -9,6 +9,7 @@ namespace pimoroni { int PicoGraphics::create_pen(uint8_t r, uint8_t g, uint8_t b) {return -1;}; void PicoGraphics::set_pixel_dither(const Point &p, const RGB &c) {}; void PicoGraphics::set_pixel_dither(const Point &p, const RGB565 &c) {}; + void PicoGraphics::set_pixel_dither(const Point &p, const uint8_t &c) {}; void PicoGraphics::scanline_convert(PenType type, conversion_callback_func callback) {}; void PicoGraphics::sprite(void* data, const Point &sprite, const Point &dest, const int scale, const int transparent) {}; diff --git a/libraries/pico_graphics/pico_graphics.hpp b/libraries/pico_graphics/pico_graphics.hpp index 998d5b35..29641d48 100644 --- a/libraries/pico_graphics/pico_graphics.hpp +++ b/libraries/pico_graphics/pico_graphics.hpp @@ -217,6 +217,7 @@ namespace pimoroni { virtual int reset_pen(uint8_t i); virtual void set_pixel_dither(const Point &p, const RGB &c); virtual void set_pixel_dither(const Point &p, const RGB565 &c); + virtual void set_pixel_dither(const Point &p, const uint8_t &c); virtual void scanline_convert(PenType type, conversion_callback_func callback); virtual void sprite(void* data, const Point &sprite, const Point &dest, const int scale, const int transparent); @@ -256,6 +257,7 @@ namespace pimoroni { void set_pixel(const Point &p) override; void set_pixel_span(const Point &p, uint l) override; + void set_pixel_dither(const Point &p, const uint8_t &c) override; static size_t buffer_size(uint w, uint h) { return w * h / 8; @@ -272,6 +274,7 @@ namespace pimoroni { void set_pixel(const Point &p) override; void set_pixel_span(const Point &p, uint l) override; + void set_pixel_dither(const Point &p, const uint8_t &c) override; static size_t buffer_size(uint w, uint h) { return w * h / 8; diff --git a/libraries/pico_graphics/pico_graphics_pen_1bit.cpp b/libraries/pico_graphics/pico_graphics_pen_1bit.cpp index ef0f2d0b..4a24bab6 100644 --- a/libraries/pico_graphics/pico_graphics_pen_1bit.cpp +++ b/libraries/pico_graphics/pico_graphics_pen_1bit.cpp @@ -57,4 +57,14 @@ namespace pimoroni { } } + void PicoGraphics_Pen1Bit::set_pixel_dither(const Point &p, const uint8_t &c) { + if(!bounds.contains(p)) return; + + uint8_t _dmv = dither16_pattern[(p.x & 0b11) | ((p.y & 0b11) << 2)]; + uint8_t _dc = c >> 4; + color = _dc > _dmv ? 1 : 0; + + set_pixel(p); + }; + } \ No newline at end of file diff --git a/libraries/pico_graphics/pico_graphics_pen_1bitY.cpp b/libraries/pico_graphics/pico_graphics_pen_1bitY.cpp index 0fa14d02..821ab090 100644 --- a/libraries/pico_graphics/pico_graphics_pen_1bitY.cpp +++ b/libraries/pico_graphics/pico_graphics_pen_1bitY.cpp @@ -40,4 +40,14 @@ namespace pimoroni { } } + void PicoGraphics_Pen1BitY::set_pixel_dither(const Point &p, const uint8_t &c) { + if(!bounds.contains(p)) return; + + uint8_t _dmv = dither16_pattern[(p.x & 0b11) | ((p.y & 0b11) << 2)]; + uint8_t _dc = c >> 4; + color = _dc > _dmv ? 1 : 0; + + set_pixel(p); + }; + } \ No newline at end of file diff --git a/micropython/modules/jpegdec/jpegdec.cpp b/micropython/modules/jpegdec/jpegdec.cpp index d3ad01d8..2c18e268 100644 --- a/micropython/modules/jpegdec/jpegdec.cpp +++ b/micropython/modules/jpegdec/jpegdec.cpp @@ -22,6 +22,7 @@ typedef struct _ModPicoGraphics_obj_t { typedef struct _JPEG_obj_t { mp_obj_base_t base; JPEGDEC *jpeg; + void *dither_buffer; mp_obj_t file; mp_buffer_info_t buf; ModPicoGraphics_obj_t *graphics; @@ -85,7 +86,15 @@ MICROPY_EVENT_POLL_HOOK // "pixel" is slow and clipped, // guaranteeing we wont draw jpeg data out of the framebuffer.. // Can we clip beforehand and make this faster? - if(pDraw->iBpp == 4) { + if(pDraw->iBpp == 8) { + uint8_t *pixel = (uint8_t *)pDraw->pPixels; + for(int y = 0; y < pDraw->iHeight; y++) { + for(int x = 0; x < pDraw->iWidth; x++) { + current_graphics->set_pixel_dither({pDraw->x + x, pDraw->y + y}, *pixel); + pixel++; + } + } + } else if(pDraw->iBpp == 4) { uint8_t *pixels = (uint8_t *)pDraw->pPixels; for(int y = 0; y < pDraw->iHeight; y++) { for(int x = 0; x < pDraw->iWidth; x++) { @@ -146,6 +155,7 @@ mp_obj_t _JPEG_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, c self->base.type = &JPEG_type; self->jpeg = m_new_class(JPEGDEC); self->graphics = (ModPicoGraphics_obj_t *)MP_OBJ_TO_PTR(args[ARG_picographics].u_obj); + return self; } @@ -234,10 +244,8 @@ mp_obj_t _JPEG_decode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args break; // TODO 2-bit is currently unsupported case PicoGraphics::PEN_P2: - self->jpeg->setPixelType(TWO_BIT_DITHERED); - break; case PicoGraphics::PEN_1BIT: - self->jpeg->setPixelType(ONE_BIT_DITHERED); + self->jpeg->setPixelType(EIGHT_BIT_GRAYSCALE); break; } @@ -245,13 +253,7 @@ mp_obj_t _JPEG_decode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args // since the JPEGDRAW struct has no userdata current_graphics = self->graphics->graphics; - if(self->graphics->graphics->pen_type == PicoGraphics::PEN_P4 || self->graphics->graphics->pen_type == PicoGraphics::PEN_1BIT) { - uint8_t *buf = new uint8_t[2048]; - result = self->jpeg->decodeDither(x, y, buf, f); - delete[] buf; - } else { - result = self->jpeg->decode(x, y, f); - } + result = self->jpeg->decode(x, y, f); current_graphics = nullptr;