kopia lustrzana https://github.com/pimoroni/pimoroni-pico
PicoGraphics/JPEGDEC: Use PicoGraphics dither.
rodzic
9c079bb1e5
commit
12866a0b7b
|
@ -9,6 +9,7 @@ namespace pimoroni {
|
||||||
int PicoGraphics::create_pen(uint8_t r, uint8_t g, uint8_t b) {return -1;};
|
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 RGB &c) {};
|
||||||
void PicoGraphics::set_pixel_dither(const Point &p, const RGB565 &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::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) {};
|
void PicoGraphics::sprite(void* data, const Point &sprite, const Point &dest, const int scale, const int transparent) {};
|
||||||
|
|
||||||
|
|
|
@ -217,6 +217,7 @@ namespace pimoroni {
|
||||||
virtual int reset_pen(uint8_t i);
|
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 RGB &c);
|
||||||
virtual void set_pixel_dither(const Point &p, const RGB565 &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 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);
|
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(const Point &p) override;
|
||||||
void set_pixel_span(const Point &p, uint l) 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) {
|
static size_t buffer_size(uint w, uint h) {
|
||||||
return w * h / 8;
|
return w * h / 8;
|
||||||
|
@ -272,6 +274,7 @@ namespace pimoroni {
|
||||||
|
|
||||||
void set_pixel(const Point &p) override;
|
void set_pixel(const Point &p) override;
|
||||||
void set_pixel_span(const Point &p, uint l) 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) {
|
static size_t buffer_size(uint w, uint h) {
|
||||||
return w * h / 8;
|
return w * h / 8;
|
||||||
|
|
|
@ -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);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -22,6 +22,7 @@ typedef struct _ModPicoGraphics_obj_t {
|
||||||
typedef struct _JPEG_obj_t {
|
typedef struct _JPEG_obj_t {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
JPEGDEC *jpeg;
|
JPEGDEC *jpeg;
|
||||||
|
void *dither_buffer;
|
||||||
mp_obj_t file;
|
mp_obj_t file;
|
||||||
mp_buffer_info_t buf;
|
mp_buffer_info_t buf;
|
||||||
ModPicoGraphics_obj_t *graphics;
|
ModPicoGraphics_obj_t *graphics;
|
||||||
|
@ -85,7 +86,15 @@ MICROPY_EVENT_POLL_HOOK
|
||||||
// "pixel" is slow and clipped,
|
// "pixel" is slow and clipped,
|
||||||
// guaranteeing we wont draw jpeg data out of the framebuffer..
|
// guaranteeing we wont draw jpeg data out of the framebuffer..
|
||||||
// Can we clip beforehand and make this faster?
|
// 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;
|
uint8_t *pixels = (uint8_t *)pDraw->pPixels;
|
||||||
for(int y = 0; y < pDraw->iHeight; y++) {
|
for(int y = 0; y < pDraw->iHeight; y++) {
|
||||||
for(int x = 0; x < pDraw->iWidth; x++) {
|
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->base.type = &JPEG_type;
|
||||||
self->jpeg = m_new_class(JPEGDEC);
|
self->jpeg = m_new_class(JPEGDEC);
|
||||||
self->graphics = (ModPicoGraphics_obj_t *)MP_OBJ_TO_PTR(args[ARG_picographics].u_obj);
|
self->graphics = (ModPicoGraphics_obj_t *)MP_OBJ_TO_PTR(args[ARG_picographics].u_obj);
|
||||||
|
|
||||||
return self;
|
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;
|
break;
|
||||||
// TODO 2-bit is currently unsupported
|
// TODO 2-bit is currently unsupported
|
||||||
case PicoGraphics::PEN_P2:
|
case PicoGraphics::PEN_P2:
|
||||||
self->jpeg->setPixelType(TWO_BIT_DITHERED);
|
|
||||||
break;
|
|
||||||
case PicoGraphics::PEN_1BIT:
|
case PicoGraphics::PEN_1BIT:
|
||||||
self->jpeg->setPixelType(ONE_BIT_DITHERED);
|
self->jpeg->setPixelType(EIGHT_BIT_GRAYSCALE);
|
||||||
break;
|
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
|
// since the JPEGDRAW struct has no userdata
|
||||||
current_graphics = self->graphics->graphics;
|
current_graphics = self->graphics->graphics;
|
||||||
|
|
||||||
if(self->graphics->graphics->pen_type == PicoGraphics::PEN_P4 || self->graphics->graphics->pen_type == PicoGraphics::PEN_1BIT) {
|
result = self->jpeg->decode(x, y, f);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
current_graphics = nullptr;
|
current_graphics = nullptr;
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue