From 0fe94b5867227a3a5ce41f64c9087efe259d2d91 Mon Sep 17 00:00:00 2001 From: Thorinair Date: Mon, 31 Aug 2020 14:07:56 +0200 Subject: [PATCH] Add invert support, add dither starter --- Inkplate.cpp | 13 ++++++++++--- Inkplate.h | 16 ++++++++-------- TJpg_Decoder.cpp | 6 +++--- TJpg_Decoder.h | 4 ++-- .../10-Inkplate_Web_BMP_pictures.ino | 2 +- .../11-Inkplate_SD_JPEG_pictures.ino | 10 ++++------ .../12-Inkplate_Web_JPEG_pictures.ino | 11 ++++++----- tjpgd.c | 12 ++++++++++-- tjpgd.h | 4 +++- 9 files changed, 47 insertions(+), 31 deletions(-) diff --git a/Inkplate.cpp b/Inkplate.cpp index 8b32300..2a6e916 100644 --- a/Inkplate.cpp +++ b/Inkplate.cpp @@ -32,15 +32,22 @@ void ckvClock() usleep1(); } -bool jpegCallback(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* data, void* _display) { +bool jpegCallback(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* data, void* _display, bool _dither, bool _invert) { Inkplate *display = static_cast(_display); + if (_dither) { + //TODO: Implement dithering! + Serial.println(_dither); + } + int i, j; for (j = 0; j < h; j++) { for (i = 0; i < w; i++) { uint16_t rgb = data[j*w + i]; + if (_invert) + rgb = ~rgb; uint8_t px = (RED(rgb) * 2126 / 10000) + (GREEN(rgb) * 7152 / 10000) + (BLUE(rgb) * 722 / 10000); display->drawPixel(i + x, j + y, px >> 5); } @@ -561,7 +568,7 @@ int Inkplate::drawJpegFromSD(Inkplate *display, SdFile *p, int x, int y, bool di selectDisplayMode(INKPLATE_3BIT); - if(TJpgDec.drawJpg(x, y, buf, total, display) == 0) + if(TJpgDec.drawJpg(x, y, buf, total, display, dither, invert) == 0) ret = 1; free(buf); @@ -607,7 +614,7 @@ int Inkplate::drawJpegFromWeb(Inkplate *display, WiFiClient *s, int x, int y, in selectDisplayMode(INKPLATE_3BIT); - if(TJpgDec.drawJpg(x, y, buf, len, display) == 0) + if(TJpgDec.drawJpg(x, y, buf, len, display, dither, invert) == 0) ret = 1; free(buf); diff --git a/Inkplate.h b/Inkplate.h index cd88bbd..3237317 100644 --- a/Inkplate.h +++ b/Inkplate.h @@ -233,14 +233,14 @@ public: void einkOn(void); void selectDisplayMode(uint8_t _mode); uint8_t getDisplayMode(); - int drawBitmapFromSD(SdFile *p, int x, int y, bool invert = false, bool dither = false); - int drawBitmapFromSD(char *fileName, int x, int y, bool invert = false, bool dither = false); - int drawBitmapFromWeb(WiFiClient *s, int x, int y, int len, bool invert = false, bool dither = false); - int drawBitmapFromWeb(char *url, int x, int y, bool invert = false, bool dither = false); - int drawJpegFromSD(Inkplate *display, SdFile *p, int x, int y, bool invert = false, bool dither = false); - int drawJpegFromSD(Inkplate *display, char *fileName, int x, int y, bool invert = false, bool dither = false); - int drawJpegFromWeb(Inkplate *display, WiFiClient *s, int x, int y, int len, bool invert = false, bool dither = false); - int drawJpegFromWeb(Inkplate *display, char *url, int x, int y, bool invert = false, bool dither = false); + int drawBitmapFromSD(SdFile *p, int x, int y, bool dither = false, bool invert = false); + int drawBitmapFromSD(char *fileName, int x, int y, bool dither = false, bool invert = false); + int drawBitmapFromWeb(WiFiClient *s, int x, int y, int len, bool dither = false, bool invert = false); + int drawBitmapFromWeb(char *url, int x, int y, bool dither = false, bool invert = false); + int drawJpegFromSD(Inkplate *display, SdFile *p, int x, int y, bool dither = false, bool invert = false); + int drawJpegFromSD(Inkplate *display, char *fileName, int x, int y, bool dither = false, bool invert = false); + int drawJpegFromWeb(Inkplate *display, WiFiClient *s, int x, int y, int len, bool dither = false, bool invert = false); + int drawJpegFromWeb(Inkplate *display, char *url, int x, int y, bool dither = false, bool invert = false); void drawElipse(int rx, int ry, int xc, int yc, int c); void fillElipse(int rx, int ry, int xc, int yc, int c); void drawPolygon(int *x, int *y, int n, int color); diff --git a/TJpg_Decoder.cpp b/TJpg_Decoder.cpp index fe76eb5..942b4be 100644 --- a/TJpg_Decoder.cpp +++ b/TJpg_Decoder.cpp @@ -116,14 +116,14 @@ uint16_t TJpg_Decoder::jd_output(JDEC* jdec, void* bitmap, JRECT* jrect) uint16_t h = jrect->bottom + 1 - jrect->top; // Pass the image block and rendering parameters in a callback to the sketch - return thisPtr->tft_output(x, y, w, h, (uint16_t*)bitmap, (void*)jdec->_display); + return thisPtr->tft_output(x, y, w, h, (uint16_t*)bitmap, (void*)jdec->_display, jdec->_dither, jdec->_invert); } /*************************************************************************************** ** Function name: drawJpg ** Description: Draw a jpg saved in a FLASH memory array ***************************************************************************************/ -JRESULT TJpg_Decoder::drawJpg(int32_t x, int32_t y, const uint8_t jpeg_data[], uint32_t data_size, void* display) { +JRESULT TJpg_Decoder::drawJpg(int32_t x, int32_t y, const uint8_t jpeg_data[], uint32_t data_size, void* display, bool dither, bool invert) { JDEC jdec; JRESULT jresult = JDR_OK; @@ -142,7 +142,7 @@ JRESULT TJpg_Decoder::drawJpg(int32_t x, int32_t y, const uint8_t jpeg_data[], u // Extract image and render if (jresult == JDR_OK) { - jresult = jd_decomp(&jdec, jd_output, jpgScale, display); + jresult = jd_decomp(&jdec, jd_output, jpgScale, display, dither, invert); } return jresult; diff --git a/TJpg_Decoder.h b/TJpg_Decoder.h index 69fbf7d..9bdd1b3 100644 --- a/TJpg_Decoder.h +++ b/TJpg_Decoder.h @@ -30,7 +30,7 @@ enum { //------------------------------------------------------------------------------ -typedef bool (*SketchCallback)(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *data, void* display); +typedef bool (*SketchCallback)(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *data, void* display, bool dither, bool invert); class TJpg_Decoder { @@ -47,7 +47,7 @@ public: void setJpgScale(uint8_t scale); void setCallback(SketchCallback sketchCallback); - JRESULT drawJpg(int32_t x, int32_t y, const uint8_t array[], uint32_t array_size, void* display); + JRESULT drawJpg(int32_t x, int32_t y, const uint8_t array[], uint32_t array_size, void* display, bool dither, bool invert); JRESULT getJpgSize(uint16_t *w, uint16_t *h, const uint8_t array[], uint32_t array_size); void setSwapBytes(bool swap); diff --git a/examples/2. Advanced Inkplate Features/10-Inkplate_Web_BMP_pictures/10-Inkplate_Web_BMP_pictures.ino b/examples/2. Advanced Inkplate Features/10-Inkplate_Web_BMP_pictures/10-Inkplate_Web_BMP_pictures.ino index 43c8054..a2ef00f 100644 --- a/examples/2. Advanced Inkplate Features/10-Inkplate_Web_BMP_pictures/10-Inkplate_Web_BMP_pictures.ino +++ b/examples/2. Advanced Inkplate Features/10-Inkplate_Web_BMP_pictures/10-Inkplate_Web_BMP_pictures.ino @@ -52,7 +52,7 @@ void setup() { //Photo taken by: Roberto Fernandez if (!display.drawBitmapFromWeb("https://varipass.org/neowise_mono.bmp", 0, 0, false, true)) { //If is something failed (wrong filename or wrong bitmap format), write error message on the screen. - //REMEMBER! You can only use Windows Bitmap file with color depth of 1, 4, 8 or 24 bits with no compression! + //REMEMBER! You can only use Windows Bitmap file with color depth of 1, 4, 8 or 24 bits with no compression! display.println("Image open error"); display.display(); } diff --git a/examples/2. Advanced Inkplate Features/11-Inkplate_SD_JPEG_pictures/11-Inkplate_SD_JPEG_pictures.ino b/examples/2. Advanced Inkplate Features/11-Inkplate_SD_JPEG_pictures/11-Inkplate_SD_JPEG_pictures.ino index 1e6cc32..60599fb 100644 --- a/examples/2. Advanced Inkplate Features/11-Inkplate_SD_JPEG_pictures/11-Inkplate_SD_JPEG_pictures.ino +++ b/examples/2. Advanced Inkplate Features/11-Inkplate_SD_JPEG_pictures/11-Inkplate_SD_JPEG_pictures.ino @@ -26,8 +26,6 @@ Inkplate display(INKPLATE_1BIT); //Create an object on Inkplate library and a SdFile file; //Create SdFile object used for accessing files on SD card void setup() { - Serial.begin(115200); - display.begin(); //Init Inkplate library (you should call this function ONLY ONCE) display.clearDisplay(); //Clear frame buffer of display display.display(); //Put clear image on display @@ -39,12 +37,12 @@ void setup() { //If card is properly init, try to load image and display it on e-paper at position X=100, Y=0 //NOTE: These methods require you to pass a reference to the display object as first parameter. - //NOTE: Both drawJpegFromSD methods allow for an optional fifth "invert" parameter. Setting this parameter to true + //NOTE: Both drawJpegFromSD methods allow for an optional sixth "invert" parameter. Setting this parameter to true //will flip all colors on the image, making black white and white black. - //Sixth parameter will dither the image. - if (!display.drawJpegFromSD(&display, "pyramid.jpg", 100, 0, false, true)) { + //fifth parameter will dither the image. + if (!display.drawJpegFromSD(&display, "pyramid.jpg", 100, 0, true, false)) { //If is something failed (wrong filename or wrong format), write error message on the screen. - //You can turn off dithering for somewhat faster image load by changing the last true to false, or removing the argument completely + //You can turn off dithering for somewhat faster image load by changing the fifth parameter to false, or removing the parameter completely display.println("Image open error"); display.display(); } diff --git a/examples/2. Advanced Inkplate Features/12-Inkplate_Web_JPEG_pictures/12-Inkplate_Web_JPEG_pictures.ino b/examples/2. Advanced Inkplate Features/12-Inkplate_Web_JPEG_pictures/12-Inkplate_Web_JPEG_pictures.ino index 9ed62ca..a002961 100644 --- a/examples/2. Advanced Inkplate Features/12-Inkplate_Web_JPEG_pictures/12-Inkplate_Web_JPEG_pictures.ino +++ b/examples/2. Advanced Inkplate Features/12-Inkplate_Web_JPEG_pictures/12-Inkplate_Web_JPEG_pictures.ino @@ -20,10 +20,11 @@ #include "WiFi.h" //Include library for WiFi Inkplate display(INKPLATE_1BIT); //Create an object on Inkplate library and also set library into 1 Bit mode (Monochrome) -const char* ssid = "Twilight Sparkle"; //Your WiFi SSID -const char* password = "thori4twily"; //Your WiFi password +const char* ssid = ""; //Your WiFi SSID +const char* password = ""; //Your WiFi password void setup() { + Serial.begin(115200); display.begin(); //Init Inkplate library (you should call this function ONLY ONCE) display.clearDisplay(); //Clear frame buffer of display display.display(); //Put clear image on display @@ -44,10 +45,10 @@ void setup() { //Try to load image and display it on e-paper at position X=0, Y=100 //NOTE: These methods require you to pass a reference to the display object as first parameter. - //NOTE: Both drawJpegFromWeb methods allow for an optional fifth "invert" parameter. Setting this parameter to true + //NOTE: Both drawJpegFromWeb methods allow for an optional sisxth "invert" parameter. Setting this parameter to true //will flip all colors on the image, making black white and white black. - //Sixth parameter will dither the image. - if (!display.drawJpegFromWeb(&display, "https://varipass.org/destination.jpg", 0, 100, false, true)) { + //fifth parameter will dither the image. + if (!display.drawJpegFromWeb(&display, "https://varipass.org/destination.jpg", 0, 100, true, false)) { //If is something failed (wrong filename or format), write error message on the screen. display.println("Image open error"); display.display(); diff --git a/tjpgd.c b/tjpgd.c index 301c5d0..4b3321e 100644 --- a/tjpgd.c +++ b/tjpgd.c @@ -947,7 +947,9 @@ JRESULT jd_decomp ( JDEC* jd, /* Initialized decompression object */ uint16_t (*outfunc)(JDEC*, void*, JRECT*), /* RGB output function */ uint8_t scale, /* Output de-scaling factor (0 to 3) */ - void* display + void* display, + uint8_t dither, + uint8_t invert ) { uint16_t x, y, mx, my; @@ -958,6 +960,8 @@ JRESULT jd_decomp ( if (scale > (JD_USE_SCALE ? 3 : 0)) return JDR_PAR; jd->scale = scale; jd->_display = display; + jd->_dither = dither; + jd->_invert = invert; mx = jd->msx * 8; my = jd->msy * 8; /* Size of the MCU (pixel) */ @@ -1921,7 +1925,9 @@ JRESULT jd_decomp ( JDEC* jd, /* Initialized decompression object */ uint16_t (*outfunc)(JDEC*, void*, JRECT*), /* RGB output function */ uint8_t scale, /* Output de-scaling factor (0 to 3) */ - void* display + void* display, + uint8_t dither, + uint8_t invert ) { uint16_t x, y, mx, my; @@ -1932,6 +1938,8 @@ JRESULT jd_decomp ( if (scale > (JD_USE_SCALE ? 3 : 0)) return JDR_PAR; jd->scale = scale; jd->_display = display; + jd->_dither = dither; + jd->_invert = invert; mx = jd->msx * 8; my = jd->msy * 8; /* Size of the MCU (pixel) */ diff --git a/tjpgd.h b/tjpgd.h index ed26f5b..29cd7f9 100644 --- a/tjpgd.h +++ b/tjpgd.h @@ -77,11 +77,13 @@ struct JDEC_s { void* device; /* Pointer to I/O device identifiler for the session */ uint8_t swap; /* Added by Bodmer to control byte swapping */ void* _display; + uint8_t _dither; + uint8_t _invert; }; /* TJpgDec API functions */ JRESULT jd_prepare (JDEC*, uint16_t(*)(JDEC*,uint8_t*,uint16_t), void*, uint16_t, void*); -JRESULT jd_decomp (JDEC*, uint16_t(*)(JDEC*,void*,JRECT*), uint8_t, void*); +JRESULT jd_decomp (JDEC*, uint16_t(*)(JDEC*,void*,JRECT*), uint8_t, void*, uint8_t, uint8_t); #ifdef __cplusplus