Add invert support, add dither starter

This commit is contained in:
Thorinair 2020-08-31 14:07:56 +02:00
parent cef06b82d6
commit 0fe94b5867
9 changed files with 47 additions and 31 deletions

View File

@ -32,15 +32,22 @@ void ckvClock()
usleep1(); 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<Inkplate *>(_display); Inkplate *display = static_cast<Inkplate *>(_display);
if (_dither) {
//TODO: Implement dithering!
Serial.println(_dither);
}
int i, j; int i, j;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
for (i = 0; i < w; i++) for (i = 0; i < w; i++)
{ {
uint16_t rgb = data[j*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); uint8_t px = (RED(rgb) * 2126 / 10000) + (GREEN(rgb) * 7152 / 10000) + (BLUE(rgb) * 722 / 10000);
display->drawPixel(i + x, j + y, px >> 5); 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); 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; ret = 1;
free(buf); free(buf);
@ -607,7 +614,7 @@ int Inkplate::drawJpegFromWeb(Inkplate *display, WiFiClient *s, int x, int y, in
selectDisplayMode(INKPLATE_3BIT); 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; ret = 1;
free(buf); free(buf);

View File

@ -233,14 +233,14 @@ public:
void einkOn(void); void einkOn(void);
void selectDisplayMode(uint8_t _mode); void selectDisplayMode(uint8_t _mode);
uint8_t getDisplayMode(); uint8_t getDisplayMode();
int drawBitmapFromSD(SdFile *p, 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 invert = false, bool dither = 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 invert = false, bool dither = 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 invert = false, bool dither = 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 invert = false, bool dither = 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 invert = false, bool dither = 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 invert = false, bool dither = 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 invert = false, bool dither = 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 drawElipse(int rx, int ry, int xc, int yc, int c);
void fillElipse(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); void drawPolygon(int *x, int *y, int n, int color);

View File

@ -116,14 +116,14 @@ uint16_t TJpg_Decoder::jd_output(JDEC* jdec, void* bitmap, JRECT* jrect)
uint16_t h = jrect->bottom + 1 - jrect->top; uint16_t h = jrect->bottom + 1 - jrect->top;
// Pass the image block and rendering parameters in a callback to the sketch // 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 ** Function name: drawJpg
** Description: Draw a jpg saved in a FLASH memory array ** 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; JDEC jdec;
JRESULT jresult = JDR_OK; 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 // Extract image and render
if (jresult == JDR_OK) { if (jresult == JDR_OK) {
jresult = jd_decomp(&jdec, jd_output, jpgScale, display); jresult = jd_decomp(&jdec, jd_output, jpgScale, display, dither, invert);
} }
return jresult; return jresult;

View File

@ -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 { class TJpg_Decoder {
@ -47,7 +47,7 @@ public:
void setJpgScale(uint8_t scale); void setJpgScale(uint8_t scale);
void setCallback(SketchCallback sketchCallback); 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); JRESULT getJpgSize(uint16_t *w, uint16_t *h, const uint8_t array[], uint32_t array_size);
void setSwapBytes(bool swap); void setSwapBytes(bool swap);

View File

@ -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 SdFile file; //Create SdFile object used for accessing files on SD card
void setup() { void setup() {
Serial.begin(115200);
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE) display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
display.clearDisplay(); //Clear frame buffer of display display.clearDisplay(); //Clear frame buffer of display
display.display(); //Put clear image on 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 //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: 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. //will flip all colors on the image, making black white and white black.
//Sixth parameter will dither the image. //fifth parameter will dither the image.
if (!display.drawJpegFromSD(&display, "pyramid.jpg", 100, 0, false, true)) { 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. //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.println("Image open error");
display.display(); display.display();
} }

View File

@ -20,10 +20,11 @@
#include "WiFi.h" //Include library for WiFi #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) 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* ssid = ""; //Your WiFi SSID
const char* password = "thori4twily"; //Your WiFi password const char* password = ""; //Your WiFi password
void setup() { void setup() {
Serial.begin(115200);
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE) display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
display.clearDisplay(); //Clear frame buffer of display display.clearDisplay(); //Clear frame buffer of display
display.display(); //Put clear image on 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 //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: 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. //will flip all colors on the image, making black white and white black.
//Sixth parameter will dither the image. //fifth parameter will dither the image.
if (!display.drawJpegFromWeb(&display, "https://varipass.org/destination.jpg", 0, 100, false, true)) { 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. //If is something failed (wrong filename or format), write error message on the screen.
display.println("Image open error"); display.println("Image open error");
display.display(); display.display();

12
tjpgd.c
View File

@ -947,7 +947,9 @@ JRESULT jd_decomp (
JDEC* jd, /* Initialized decompression object */ JDEC* jd, /* Initialized decompression object */
uint16_t (*outfunc)(JDEC*, void*, JRECT*), /* RGB output function */ uint16_t (*outfunc)(JDEC*, void*, JRECT*), /* RGB output function */
uint8_t scale, /* Output de-scaling factor (0 to 3) */ 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; uint16_t x, y, mx, my;
@ -958,6 +960,8 @@ JRESULT jd_decomp (
if (scale > (JD_USE_SCALE ? 3 : 0)) return JDR_PAR; if (scale > (JD_USE_SCALE ? 3 : 0)) return JDR_PAR;
jd->scale = scale; jd->scale = scale;
jd->_display = display; jd->_display = display;
jd->_dither = dither;
jd->_invert = invert;
mx = jd->msx * 8; my = jd->msy * 8; /* Size of the MCU (pixel) */ 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 */ JDEC* jd, /* Initialized decompression object */
uint16_t (*outfunc)(JDEC*, void*, JRECT*), /* RGB output function */ uint16_t (*outfunc)(JDEC*, void*, JRECT*), /* RGB output function */
uint8_t scale, /* Output de-scaling factor (0 to 3) */ 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; uint16_t x, y, mx, my;
@ -1932,6 +1938,8 @@ JRESULT jd_decomp (
if (scale > (JD_USE_SCALE ? 3 : 0)) return JDR_PAR; if (scale > (JD_USE_SCALE ? 3 : 0)) return JDR_PAR;
jd->scale = scale; jd->scale = scale;
jd->_display = display; jd->_display = display;
jd->_dither = dither;
jd->_invert = invert;
mx = jd->msx * 8; my = jd->msy * 8; /* Size of the MCU (pixel) */ mx = jd->msx * 8; my = jd->msy * 8; /* Size of the MCU (pixel) */

View File

@ -77,11 +77,13 @@ struct JDEC_s {
void* device; /* Pointer to I/O device identifiler for the session */ void* device; /* Pointer to I/O device identifiler for the session */
uint8_t swap; /* Added by Bodmer to control byte swapping */ uint8_t swap; /* Added by Bodmer to control byte swapping */
void* _display; void* _display;
uint8_t _dither;
uint8_t _invert;
}; };
/* TJpgDec API functions */ /* TJpgDec API functions */
JRESULT jd_prepare (JDEC*, uint16_t(*)(JDEC*,uint8_t*,uint16_t), void*, uint16_t, void*); 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 #ifdef __cplusplus